1题目说明
在许多(较旧的)串行通信协议中,每个数据字节都与一个起始位和一个停止位一起发送,以帮助接收器从位流中分隔字节。一种常见的方案是使用一个起始位 (0)、8 个数据位和 1 个停止位 (1)。当没有传输任何内容(空闲)时,该线路也处于逻辑 1。
设计一个有限状态机,当给定比特流时,该机器将识别何时正确接收了字节。它需要识别起始位,等待所有 8 个数据位,然后验证停止位是否正确。如果停止位没有按预期出现,则 FSM 必须等到它找到停止位,然后才能尝试接收下一个字节。
一些时序图
无错误:
未找到停止位。第一个字节被丢弃:
模块端口声明
module top_module( input clk, input in, input reset, // Synchronous reset output done );
2题目解析
串口接收问题,题目没给状态图,需要自己绘制:
module top_module( input logic clk, input logic in, input logic reset, // Synchronous reset output logic done ); //define state typedef enum logic [3:0] { idle = 4'd0 , start = 4'd1 , receive_1 = 4'd2, receive_2 = 4'd3, receive_3 = 4'd4, receive_4 = 4'd5, receive_5 = 4'd6, receive_6 = 4'd7, receive_7 = 4'd8, receive_8 = 4'd9, stop = 4'd10 , waite = 4'd11 } state_def ; state_def cur_state , next_state ; var logic [3:0] state_cout ; //describe state transition logic use combinational logic always_comb begin case (cur_state) idle: begin if (!in) begin next_state = start ; end else begin next_state = idle ; end end start: begin next_state = receive_1 ; end receive_1: begin next_state = receive_2 ; end receive_2: begin next_state = receive_3 ; end receive_3: begin next_state = receive_4 ; end receive_4: begin next_state = receive_5 ; end receive_5: begin next_state = receive_6 ; end receive_6: begin next_state = receive_7 ; end receive_7: begin next_state = receive_8 ; end receive_8: begin if (!in) begin next_state = waite ; end else begin next_state = stop ; end end stop: begin if (!in) begin next_state = start ; end else begin next_state =idle ; end end waite: begin if (!in) begin next_state = waite ; end else begin next_state = idle ; end end default: begin next_state = idle ; end endcase end //descibe state sequencer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= idle ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign done = (cur_state == stop) ; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无波形。
这一题就结束了。
Part3Problem 135-Fsm_serialdata
3题目说明
上一题用一个有限状态机可以识别串行比特流中的字节何时被正确接收,添加一个数据路径将输出正确接收的数据字节。out_byte在done为1时需要有效,否则不关心。
请注意,串行协议首先发送最低有效位。
一些时序图
无错误:
模块端口声明
module top_module( input clk, input in, input reset, // Synchronous reset output [7:0] out_byte, output done );
4题目解析
状态机与上题一致。
module top_module( input logic clk, input logic in, input logic reset, // Synchronous reset output [7:0] out_byte, output logic done ); //define state typedef enum logic [3:0] { idle = 4'd0 , start = 4'd1 , receive_1 = 4'd2, receive_2 = 4'd3, receive_3 = 4'd4, receive_4 = 4'd5, receive_5 = 4'd6, receive_6 = 4'd7, receive_7 = 4'd8, receive_8 = 4'd9, stop = 4'd10 , waite = 4'd11 } state_def ; state_def cur_state , next_state ; var logic [3:0] state_cout ; //describe state transition logic use combinational logic always_comb begin case (cur_state) idle: begin if (!in) begin next_state = start ; end else begin next_state = idle ; end end start: begin next_state = receive_1 ; end receive_1: begin next_state = receive_2 ; end receive_2: begin next_state = receive_3 ; end receive_3: begin next_state = receive_4 ; end receive_4: begin next_state = receive_5 ; end receive_5: begin next_state = receive_6 ; end receive_6: begin next_state = receive_7 ; end receive_7: begin next_state = receive_8 ; end receive_8: begin if (!in) begin next_state = waite ; end else begin next_state = stop ; end end stop: begin if (!in) begin next_state = start ; end else begin next_state =idle ; end end waite: begin if (!in) begin next_state = waite ; end else begin next_state = idle ; end end default: begin next_state = idle ; end endcase end //descibe state sequencer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= idle ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign done = (cur_state == stop) ; assign out_byte = done ? out_bytes_temp : 8'd0 ; var logic [7:0] out_bytes_temp ; always_ff @( posedge clk ) begin if (next_state == receive_1) begin out_bytes_temp[0] <= in ; end else if (next_state == receive_2) begin out_bytes_temp[1] <= in ; end else if (next_state == receive_3) begin out_bytes_temp[2] <= in ; end else if (next_state == receive_4) begin out_bytes_temp[3] <= in ; end else if (next_state == receive_5) begin out_bytes_temp[4] <= in ; end else if (next_state == receive_6) begin out_bytes_temp[5] <= in ; end else if (next_state == receive_7) begin out_bytes_temp[6] <= in ; end else if (next_state == receive_8) begin out_bytes_temp[7] <= in ; end end endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无波形。
这一题就结束了。
Part4Problem 136-Fsm_serialdp
5题目说明
这题仍然是在前面的基础上进行进化,增添了奇偶校验位。奇偶校验(Parity Check)是一种校验代码传输正确性的方法。根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。奇偶校验是在传输中保障数据接收正确的常用方法,也是最初级的校验方式。
该题采用的是奇校验的方式,并且提供了奇偶校验模块。原本 start 和 stop 位之间的8 bit 变为了9 bit,新增的1 bit 为奇校验位,从而使得这9 bit 中“1”的数量为奇数个,即题目中提供的奇偶校验模块输出为1时表面数据正确,否则数据错误不予接收。波形图如下所示。
module parity ( input clk, input reset, input in, output reg odd); always @(posedge clk) if (reset) odd <= 0; else if (in) odd <= ~odd; endmodule
请注意,串行协议首先发送最低有效位,然后在 8 个数据位之后发送奇偶校验位。
一些时序图
模块端口声明
module top_module( input clk, input in, input reset, // Synchronous reset output [7:0] out_byte, output done );
6题目解析
module top_module( input logic clk, input logic in, input logic reset, // Synchronous reset output [7:0] out_byte, output logic done ); // Modify FSM and datapath from Fsm_serialdata //define state typedef enum logic [3:0] { idle = 4'd0 , start = 4'd1 , receive_1 = 4'd2, receive_2 = 4'd3, receive_3 = 4'd4, receive_4 = 4'd5, receive_5 = 4'd6, receive_6 = 4'd7, receive_7 = 4'd8, receive_8 = 4'd9, stop = 4'd10 , waite = 4'd11 , parity = 4'd12 } state_def ; state_def cur_state , next_state ; wire logic odd ; //describe state transition logic use combinational logic always_comb begin case (cur_state) idle: begin if (!in) begin next_state = start ; end else begin next_state = idle ; end end start: begin next_state = receive_1 ; end receive_1: begin next_state = receive_2 ; end receive_2: begin next_state = receive_3 ; end receive_3: begin next_state = receive_4 ; end receive_4: begin next_state = receive_5 ; end receive_5: begin next_state = receive_6 ; end receive_6: begin next_state = receive_7 ; end receive_7: begin next_state = receive_8 ; end receive_8: begin next_state = parity ; end parity: begin if (!in) begin next_state = waite ; end else begin next_state = stop ; end end stop: begin if (!in) begin next_state = start ; end else begin next_state =idle ; end end waite: begin if (!in) begin next_state = waite ; end else begin next_state = idle ; end end default: begin next_state = idle ; end endcase end //descibe state sequencer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= idle ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign reset_en = (reset == 1'd1) || (next_state == stop) || (next_state == idle) || (next_state == start) ; wire logic reset_en ; var logic [7:0] out_bytes_temp ; always_ff @( posedge clk ) begin if (next_state == receive_1) begin out_bytes_temp[0] <= in ; end else if (next_state == receive_2) begin out_bytes_temp[1] <= in ; end else if (next_state == receive_3) begin out_bytes_temp[2] <= in ; end else if (next_state == receive_4) begin out_bytes_temp[3] <= in ; end else if (next_state == receive_5) begin out_bytes_temp[4] <= in ; end else if (next_state == receive_6) begin out_bytes_temp[5] <= in ; end else if (next_state == receive_7) begin out_bytes_temp[6] <= in ; end else if (next_state == receive_8) begin out_bytes_temp[7] <= in ; end end always_ff @( posedge clk ) begin if (reset) begin out_byte <= 8'd0 ; done <= 1'd0 ; end else if (next_state == stop && odd == 1'd1) begin out_byte <= out_bytes_temp ; done <= 1'd1 ; end else begin out_byte <= 8'd0 ; done <= 1'd0 ; end end // New: Add parity checking. parity u_parity ( .clk(clk), .reset(reset_en), .in(in), .odd(odd) ); endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无波形。
这一题就结束了。
Part5Problem 137-Fsm_hdlc
7题目说明
同步HDLC帧涉及从连续的比特流中解码寻找某一帧(即数据包)的开始和结束位置的位模式。(对位模式不太理解的可以参见https://zhuanlan.zhihu.com/p/46317118)。如果接收到连续的6个1(即01111110),即是帧边界的“标志”。同时为了避免输入的数据流中意外包含这个帧边界“标志”,数据的发送方必须在数据中连续的5个1之后插入一个0,而数据的接收方必须将这个多余的0检测出来并丢弃掉。同时,如果输入检测到了了连续7个或更多的1时,接收方还需要发出错误信号。
创建一个有限状态机来识别这三个序列:
0111110 : 信号位需要被丢弃(disc)。
01111110:标记帧的开始/结束 ( flag )。
01111111...:错误(7 个或更多 1)(错误)。
当 FSM 被重置时,它应该处于一种状态,就像之前的输入为 0 一样。
以下是说明所需操作的一些示例序列。
丢弃0111110:
图片来自HDLBits
标志01111110:
图片来自HDLBits
重置和错误01111111...:
图片来自HDLBits
实现这个状态机。
模块端口声明
module top_module( input clk, input reset, // Synchronous reset input in, output disc, output flag, output err);
8题目解析
1、请使用10个状态以内的摩尔机。
2、状态图:
module top_module( input logic clk, input logic reset, // Synchronous reset input logic in, output logic disc, output logic flag, output logic err ); //define state typedef enum logic [2:0] { detect_0 = 3'd0 , receive_1 = 3'd1 , receive_2 = 3'd2 , receive_3 = 3'd3 , receive_4 = 3'd4 , receive_5 = 3'd5 , receive_6 = 3'd6 , receive_7 = 3'd7 } state_def ; state_def cur_state , next_state ; //describe state transition logic use combinational logic always_comb begin case (cur_state) detect_0: begin next_state = in ? receive_1 : detect_0 ; end receive_1: begin next_state = in ? receive_2 : detect_0 ; end receive_2: begin next_state = in ? receive_3 : detect_0 ; end receive_3: begin next_state = in ? receive_4 : detect_0 ; end receive_4: begin next_state = in ? receive_5 : detect_0 ; end receive_5: begin next_state = in ? receive_6 : detect_0 ; end receive_6: begin next_state = in ? receive_7 : detect_0 ; end receive_7: begin next_state = in ? receive_7 : detect_0 ; end default: begin next_state = detect_0 ; end endcase end //describe state sequecer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= detect_0 ; end else begin cur_state <= next_state ; end end //describe output decoder use sequential and combinational logic always_ff @( posedge clk ) begin if (reset) begin disc <= 1'd0 ; flag <= 1'd0 ; end else begin case (1'd1) (cur_state == receive_5) && (next_state == detect_0): disc <= 1'd1 ; (cur_state == receive_6) && (next_state == detect_0): flag <= 1'd1 ; default : begin disc <= 1'd0 ; flag <= 1'd0 ; end endcase end end assign err = (cur_state == receive_7) ; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无波形。
这一题就结束了。
Part6Problem 138-ece241_2013_q8
9题目说明
设计一个单输入单输出串行 2 的互补摩尔状态机。输入 (x) 是一系列位(每个时钟周期一个),从数字的最低有效位开始,输出 (Z) 是输入的 2 的补码。机器将接受任意长度的输入数字。该电路需要异步复位。转换在Reset释放时开始,在Reset置位时停止。
例如:
模块端口声明
module top_module ( input clk, input areset, input x, output z );
10题目解析
米里型的输出由当前状态和输入信号的组合逻辑实现,输出信号与输入信号同步。
而摩尔型状态机的输出仅由当前状态决定,与输入信号异步,往往存在延迟。
module top_module ( input logic clk, input logic aresetn, // Asynchronous active-low reset input logic x, output logic z ); //define state typedef enum logic [1:0] { idle = 2'd0 , state_1 = 2'd1 , state_2 = 2'd2 } state_def ; state_def cur_state , next_state ; //describe state sequecer use sequential logic always_ff @( posedge clk or negedge aresetn) begin if (!aresetn) begin cur_state <= idle ; end else begin cur_state <= next_state ; end end //describe state transition logic use combinational logic always_comb begin case (cur_state) idle: begin next_state = x ? state_1 : idle ; end state_1: begin next_state = x ? state_1 : state_2 ; end state_2: begin next_state = x ? state_1 : idle ; end default: begin next_state = idle ; end endcase end //describe output decoder use combinational logic assign z = (cur_state == state_2) && (x == 1'd1) ; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Part7Problem 139-ece241_2014_q5a
11题目说明
设计一个单输入单输出串行 2 的互补摩尔状态机。输入 (x) 是一系列位(每个时钟周期一个),从数字的最低有效位开始,输出 (Z) 是输入的 2 的补码。机器将接受任意长度的输入数字。该电路需要异步复位。转换在Reset释放时开始,在Reset置位时停止。
例如:
图片来自HDLBits
模块端口声明
module top_module ( input clk, input areset, input x, output z );
12题目解析
module top_module ( input logic clk, input logic areset, input logic x, output logic z ); //define state typedef enum logic [1:0] { S0 = 2'd0 , S1 = 2'd1 , S2 = 2'd2 } state_def ; state_def cur_state , next_state ; //describe state transition use combinational logic always_comb begin case (cur_state) S0: begin next_state = x ? S1 : S0 ; end S1: begin next_state = x ? S2 : S1 ; end S2: begin next_state = x ? S2 : S1 ; end default: begin next_state = S0 ; end endcase end //describe state sequencer use sequential logic always_ff @( posedge clk or posedge areset ) begin if (areset) begin cur_state <= S0 ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign z = (cur_state == S1) ; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Part8Problem 140-23_ece241_2014_q5b
13题目说明
本题和上一题 Serial two's complementer (Moore FSM) 一样,使用状态机实现一个二进制补码生成器,不同的是此题使用米里型状态机实现。
图片来自HDLBits
模块端口声明
module top_module ( input clk, input areset, input x, output z );
14题目解析
存在两个状态,复位状态 A,在输入 x 为 1 后状态转移为 B,并保持在状态 B。
状态 A 中输出 z 与输入 x 相同;状态 B 中输出 z 与输入 x 相反。
module top_module ( input logic clk, input logic areset, input logic x, output logic z ); //define state typedef enum logic { S0 = 1'd0 , S1 = 1'd1 } state_def ; state_def cur_state , next_state ; //describe state transition use combinational logic always_comb begin case (cur_state) S0: begin next_state = x ? S1 : S0 ; end S1: begin next_state = S1 ; end default: begin next_state = S0 ; end endcase end //describe state sequencer use sequential logic always_ff @( posedge clk or posedge areset ) begin if (areset) begin cur_state <= S0 ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign z = ((cur_state == S0) && (x == 1'd1)) || ((cur_state == S1 ) && (x == 1'd0)); endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Part9Problem 141-2014_q3fsm
15题目说明
考虑具有输入s和w的有限状态机。假设 FSM 开始于称为A的重置状态,如下所示。只要s = 0, FSM 就保持在状态A ,当s = 1 时,它会移动到状态B。一旦进入状态B,FSM在接下来的三个时钟周期内检查输入w的值。如果在这些时钟周期中恰好有两个时钟周期内w = 1,则 FSM 必须 在下一个时钟周期内将输出z设置为 1。否则z必须为 0。FSM 继续检查w对于接下来的三个时钟周期,依此类推。下面的时序图说明了不同w值所需的z值。
使用尽可能少的状态。请注意,s输入仅在状态A中使用,因此只需考虑w输入。
图片来自HDLBits
模块端口声明
module top_module ( input clk, input reset, // Synchronous reset input s, input w, output z );
16题目解析
值得注意的是:需要三个周期中 exactly 两个周期为 1 。
module top_module ( input logic clk, input logic reset, // Synchronous reset input logic s, input logic w, output logic z ); //define state typedef enum logic { A = 1'd0 , B = 1'd1 } state_def ; state_def cur_state , next_state ; //describe state transition use combinational logic always_comb begin case (cur_state) A: begin next_state = s ? B : A ; end B: begin next_state = B ; end default: begin next_state = A ; end endcase end //describe state sequencer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= A ; end else begin cur_state <= next_state ; end end //define counter use sequential and combinational logic var logic [1:0] count , count_c; wire logic resetn ; assign resetn = (count_c == 2'd3) ? 1'd0 : 1'd1 ; always_ff @( posedge clk ) begin if(reset) begin count <= 2'd0 ; end else if (!resetn) begin if(w == 1'd1) begin count <= 2'd1 ; end else begin count <= 2'd0 ; end end else begin if (cur_state == B && w == 1'd1) begin count <= count + 2'd1 ; end else begin count <= count ; end end end always_ff @( posedge clk ) begin if (reset) begin count_c <= 2'd0 ; end else begin if (cur_state == B && count_c == 2'd3) begin count_c <= 2'd1 ; end else if (cur_state == B) begin count_c <= count_c + 2'd1 ; end else begin count_c <= count_c ; end end end //describe output decoder use combinational logic always_ff@(posedge clk) begin if(reset) begin z <= 1'd0 ; end else begin case( 1'd1 ) (cur_state == B && count_c == 2'd2 && count == 1 && w == 1) : begin z <= 1'd1 ; end (cur_state == B && count_c == 2'd2 && count == 2 && w == 0) : begin z <= 1'd1 ; end default : begin z <= 1'd0 ; end endcase end end endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无波形。
这一题就结束了。
Part10Problem 142-2014_q3bfsm
17题目说明
这是一道简单的根据状态转移实现状态机的题目,实现完整的三段式状态机
图片来自HDLBits
模块端口声明
module top_module ( input clk, input reset, // Synchronous reset input x, output z );
18题目解析
module top_module ( input logic clk, input logic reset, // Synchronous reset input logic x, output logic z ); //define state typedef enum logic [2:0] { S0 = 3'b000 , S1 = 3'b001 , S2 = 3'b010 , S3 = 3'b011 , S4 = 3'b100 } state_def ; state_def cur_state , next_state ; //describe state transition use combinational logic always_comb begin case (cur_state) S0: begin next_state = x ? S1 : S0 ; end S1: begin next_state = x ? S4 : S1 ; end S2: begin next_state = x ? S1 : S2 ; end S3: begin next_state = x ? S2 : S1 ; end S4: begin next_state = x ? S4 : S3 ; end default: begin next_state = S0 ; end endcase end //describe state sequencer use sequential logic always_ff @( posedge clk ) begin if (reset) begin cur_state <= S0 ; end else begin cur_state <= next_state ; end end //describe output decoder use combinational logic assign z = (cur_state == S3) || (cur_state == S4) ; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中无参考波形。
这一题就结束了。
Part11总结
今天的几道题就结束了,对于状态机的理解还是有益处的,三段式状态机是题目一直推崇的,类似状态机的公示,可以“套”进去。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !