网站设计就业怎么样/百度推广和优化哪个好
Part1HDLBits: 在线学习 SystemVerilog(二十)-Problem 134-142(状态机三)

HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~
网址如下:
https://hdlbits.01xz.net/
关于HDLBits的Verilog实现可以查看下面专栏:
https://www.zhihu.com/column/c_1131528588117385216
缩略词索引:
SV:SystemVerilog
从今天开始新的一章-时序电路,包括触发器、计数器、移位寄存器、状态机等。
今天主要更新状态机,状态机基本是整个HDL中的核心,合理、高效地使用状态机,是数字电路中的重要技能。
Part2Problem 134-Fsm_serial
1题目说明
在许多(较旧的)串行通信协议中,每个数据字节都与一个起始位和一个停止位一起发送,以帮助接收器从位流中分隔字节。一种常见的方案是使用一个起始位 (0)、8 个数据位和 1 个停止位 (1)。当没有传输任何内容(空闲)时,该线路也处于逻辑 1。
设计一个有限状态机,当给定比特流时,该机器将识别何时正确接收了字节。它需要识别起始位,等待所有 8 个数据位,然后验证停止位是否正确。如果停止位没有按预期出现,则 FSM 必须等到它找到停止位,然后才能尝试接收下一个字节。
一些时序图
无错误:

未找到停止位。第一个字节被丢弃:

模块端口声明
module top_module(input clk,input in,input reset, // Synchronous resetoutput done
);
2题目解析
串口接收问题,题目没给状态图,需要自己绘制:

module top_module(input logic clk,input logic in,input logic reset, // Synchronous resetoutput 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 logicalways_comb begin case (cur_state)idle: beginif (!in) beginnext_state = start ;endelse beginnext_state = idle ;endend start: beginnext_state = receive_1 ;endreceive_1: beginnext_state = receive_2 ;endreceive_2: beginnext_state = receive_3 ;endreceive_3: beginnext_state = receive_4 ;endreceive_4: beginnext_state = receive_5 ;endreceive_5: beginnext_state = receive_6 ;endreceive_6: beginnext_state = receive_7 ;endreceive_7: beginnext_state = receive_8 ;endreceive_8: beginif (!in) beginnext_state = waite ;endelse beginnext_state = stop ;endendstop: beginif (!in) beginnext_state = start ;endelse beginnext_state =idle ;endendwaite: beginif (!in) beginnext_state = waite ;endelse beginnext_state = idle ;endenddefault: beginnext_state = idle ;endendcase
end//descibe state sequencer use sequential logicalways_ff @( posedge clk ) begin if (reset) begincur_state <= idle ;end else begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign 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 resetoutput [7:0] out_byte,output done
);
4题目解析
状态机与上题一致。
module top_module(input logic clk,input logic in,input logic reset, // Synchronous resetoutput [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 logicalways_comb begin case (cur_state)idle: beginif (!in) beginnext_state = start ;endelse beginnext_state = idle ;endend start: beginnext_state = receive_1 ;endreceive_1: beginnext_state = receive_2 ;endreceive_2: beginnext_state = receive_3 ;endreceive_3: beginnext_state = receive_4 ;endreceive_4: beginnext_state = receive_5 ;endreceive_5: beginnext_state = receive_6 ;endreceive_6: beginnext_state = receive_7 ;endreceive_7: beginnext_state = receive_8 ;endreceive_8: beginif (!in) beginnext_state = waite ;endelse beginnext_state = stop ;endendstop: beginif (!in) beginnext_state = start ;endelse beginnext_state =idle ;endendwaite: beginif (!in) beginnext_state = waite ;endelse beginnext_state = idle ;endenddefault: beginnext_state = idle ;endendcase
end//descibe state sequencer use sequential logicalways_ff @( posedge clk ) begin if (reset) begincur_state <= idle ;end else begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign 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) beginout_bytes_temp[0] <= in ;endelse if (next_state == receive_2) beginout_bytes_temp[1] <= in ;endelse if (next_state == receive_3) beginout_bytes_temp[2] <= in ;endelse if (next_state == receive_4) beginout_bytes_temp[3] <= in ;end else if (next_state == receive_5) beginout_bytes_temp[4] <= in ;endelse if (next_state == receive_6) beginout_bytes_temp[5] <= in ;endelse if (next_state == receive_7) beginout_bytes_temp[6] <= in ;endelse if (next_state == receive_8) beginout_bytes_temp[7] <= in ;endendendmodule

点击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 resetoutput [7:0] out_byte,output done
);
6题目解析
module top_module(input logic clk,input logic in,input logic reset, // Synchronous resetoutput [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 logicalways_comb begin case (cur_state)idle: beginif (!in) beginnext_state = start ;endelse beginnext_state = idle ;endend start: beginnext_state = receive_1 ;endreceive_1: beginnext_state = receive_2 ;endreceive_2: beginnext_state = receive_3 ;endreceive_3: beginnext_state = receive_4 ;endreceive_4: beginnext_state = receive_5 ;endreceive_5: beginnext_state = receive_6 ;endreceive_6: beginnext_state = receive_7 ;endreceive_7: beginnext_state = receive_8 ;endreceive_8: beginnext_state = parity ;endparity: beginif (!in) beginnext_state = waite ;endelse beginnext_state = stop ;endendstop: beginif (!in) beginnext_state = start ;endelse beginnext_state =idle ;endendwaite: beginif (!in) beginnext_state = waite ;endelse beginnext_state = idle ;endenddefault: beginnext_state = idle ;endendcase
end//descibe state sequencer use sequential logicalways_ff @( posedge clk ) begin if (reset) begincur_state <= idle ;end else begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign 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) beginout_bytes_temp[0] <= in ;endelse if (next_state == receive_2) beginout_bytes_temp[1] <= in ;endelse if (next_state == receive_3) beginout_bytes_temp[2] <= in ;endelse if (next_state == receive_4) beginout_bytes_temp[3] <= in ;end else if (next_state == receive_5) beginout_bytes_temp[4] <= in ;endelse if (next_state == receive_6) beginout_bytes_temp[5] <= in ;endelse if (next_state == receive_7) beginout_bytes_temp[6] <= in ;endelse if (next_state == receive_8) beginout_bytes_temp[7] <= in ;endendalways_ff @( posedge clk ) begin if (reset) beginout_byte <= 8'd0 ;done <= 1'd0 ;endelse if (next_state == stop && odd == 1'd1) beginout_byte <= out_bytes_temp ;done <= 1'd1 ;endelse beginout_byte <= 8'd0 ;done <= 1'd0 ;endend// 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:

标志01111110:

重置和错误01111111...:

实现这个状态机。
模块端口声明
module top_module(input clk,input reset, // Synchronous resetinput in,output disc,output flag,output err);
8题目解析
1、请使用10个状态以内的摩尔机。
2、状态图:

module top_module(input logic clk,input logic reset, // Synchronous resetinput logic in,output logic disc,output logic flag,output logic err);//define statetypedef 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 logicalways_comb begin case (cur_state)detect_0: beginnext_state = in ? receive_1 : detect_0 ;end receive_1: beginnext_state = in ? receive_2 : detect_0 ;endreceive_2: beginnext_state = in ? receive_3 : detect_0 ;endreceive_3: beginnext_state = in ? receive_4 : detect_0 ;endreceive_4: beginnext_state = in ? receive_5 : detect_0 ;endreceive_5: beginnext_state = in ? receive_6 : detect_0 ;endreceive_6: beginnext_state = in ? receive_7 : detect_0 ;endreceive_7: beginnext_state = in ? receive_7 : detect_0 ;enddefault: beginnext_state = detect_0 ;endendcaseend//describe state sequecer use sequential logic always_ff @( posedge clk ) begin if (reset) begincur_state <= detect_0 ;endelse begincur_state <= next_state ;endend//describe output decoder use sequential and combinational logicalways_ff @( posedge clk ) begin if (reset) begindisc <= 1'd0 ;flag <= 1'd0 ;endelse begincase (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 : begindisc <= 1'd0 ;flag <= 1'd0 ;endendcaseendendassign 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 resetinput logic x,output logic z ); //define statetypedef 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) begincur_state <= idle ;endelse begincur_state <= next_state ;endend//describe state transition logic use combinational logicalways_comb begin case (cur_state)idle: beginnext_state = x ? state_1 : idle ;end state_1: beginnext_state = x ? state_1 : state_2 ;endstate_2: beginnext_state = x ? state_1 : idle ;enddefault: beginnext_state = idle ;endendcaseend//describe output decoder use combinational logicassign z = (cur_state == state_2) && (x == 1'd1) ;endmodule

点击Submit,等待一会就能看到下图结果:

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Part7Problem 139-ece241_2014_q5a
11题目说明
设计一个单输入单输出串行 2 的互补摩尔状态机。输入 (x) 是一系列位(每个时钟周期一个),从数字的最低有效位开始,输出 (Z) 是输入的 2 的补码。机器将接受任意长度的输入数字。该电路需要异步复位。转换在Reset释放时开始,在Reset置位时停止。
例如:

模块端口声明
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 statetypedef 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: beginnext_state = x ? S1 : S0 ;end S1: beginnext_state = x ? S2 : S1 ;endS2: beginnext_state = x ? S2 : S1 ;enddefault: beginnext_state = S0 ;endendcase
end//describe state sequencer use sequential logicalways_ff @( posedge clk or posedge areset ) begin if (areset) begincur_state <= S0 ;endelse begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign z = (cur_state == S1) ;endmodule

点击Submit,等待一会就能看到下图结果:

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Part8Problem 140-23_ece241_2014_q5b
13题目说明
本题和上一题 Serial two's complementer (Moore FSM) 一样,使用状态机实现一个二进制补码生成器,不同的是此题使用米里型状态机实现。

模块端口声明
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 statetypedef 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: beginnext_state = x ? S1 : S0 ;end S1: beginnext_state = S1 ;enddefault: beginnext_state = S0 ;endendcase
end//describe state sequencer use sequential logicalways_ff @( posedge clk or posedge areset ) begin if (areset) begincur_state <= S0 ;endelse begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign 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输入。

模块端口声明
module top_module (input clk,input reset, // Synchronous resetinput s,input w,output z
);
16题目解析
值得注意的是:需要三个周期中 exactly 两个周期为 1 。
module top_module (input logic clk,input logic reset, // Synchronous resetinput logic s,input logic w,output logic z
);//define statetypedef 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: beginnext_state = s ? B : A ;end B: beginnext_state = B ;enddefault: beginnext_state = A ;endendcase
end//describe state sequencer use sequential logicalways_ff @( posedge clk ) begin if (reset) begincur_state <= A ;endelse begincur_state <= next_state ;end
end//define counter use sequential and combinational logicvar 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) begincount <= 2'd0 ;endelse if (!resetn) beginif(w == 1'd1) begincount <= 2'd1 ;endelse begincount <= 2'd0 ;endendelse beginif (cur_state == B && w == 1'd1) begincount <= count + 2'd1 ;endelse begincount <= count ;endend
endalways_ff @( posedge clk ) begin if (reset) begincount_c <= 2'd0 ;endelse beginif (cur_state == B && count_c == 2'd3) begincount_c <= 2'd1 ;endelse if (cur_state == B) begincount_c <= count_c + 2'd1 ;endelse begincount_c <= count_c ;endendend//describe output decoder use combinational logicalways_ff@(posedge clk) begin if(reset) beginz <= 1'd0 ;endelse begincase( 1'd1 )(cur_state == B && count_c == 2'd2 && count == 1 && w == 1) : beginz <= 1'd1 ;end(cur_state == B && count_c == 2'd2 && count == 2 && w == 0) : beginz <= 1'd1 ;enddefault : beginz <= 1'd0 ;endendcaseend
endendmodule

点击Submit,等待一会就能看到下图结果:

注意图中无波形。
这一题就结束了。
Part10Problem 142-2014_q3bfsm
17题目说明
这是一道简单的根据状态转移实现状态机的题目,实现完整的三段式状态机

模块端口声明
module top_module (input clk,input reset, // Synchronous resetinput x,output z
);
18题目解析
module top_module (input logic clk,input logic reset, // Synchronous resetinput logic x,output logic z
);//define statetypedef 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: beginnext_state = x ? S1 : S0 ;end S1: beginnext_state = x ? S4 : S1 ;endS2: beginnext_state = x ? S1 : S2 ;endS3: beginnext_state = x ? S2 : S1 ;endS4: beginnext_state = x ? S4 : S3 ;enddefault: beginnext_state = S0 ;endendcase
end//describe state sequencer use sequential logicalways_ff @( posedge clk ) begin if (reset) begincur_state <= S0 ;endelse begincur_state <= next_state ;end
end//describe output decoder use combinational logicassign z = (cur_state == S3) || (cur_state == S4) ;endmodule

点击Submit,等待一会就能看到下图结果:

注意图中无参考波形。
这一题就结束了。
Part11总结
今天的几道题就结束了,对于状态机的理解还是有益处的,三段式状态机是题目一直推崇的,类似状态机的公示,可以“套”进去。
最后我这边做题的代码也是个人理解使用,有错误欢迎大家批评指正,祝大家学习愉快~
代码链接:
https://github.com/suisuisi/SystemVerilog/tree/main/SystemVerilogHDLBits