1. 设计一个“111”串行数据检测器。要求是:当检测到连续3个或3个以上的“1”时输出为1,其他输入情况下输出为0。
(1)思路分析:参照本章前文的范例,如第224页的【例8.8】,很容易模仿或推断出这个FSM共有4个状态,分别为:
初始化时收到0的s0,然后收到1的s1,连续收到两个1的s2,连续收到3个或更多个1的s3。状态之间的
转换也很简单,收到0就跳转到s0,收到1就按收到的连续个1的个数跳到相应的状态。
(2)111 序列检测电路的源码如下:
1 //detect 111 2 //2020-10-13 3 // by YongFengXie 4 module ex8_1(clk,rst_n,x,z); 5 input clk; 6 input rst_n; 7 input x; 8 output reg z; 9 10 reg [3:0] state; 11 12 parameter s0=4'b0001, 13 s1=4'b0010, 14 s2=4'b0100, 15 s3=4'b1000; 16 17 always @(posedge clk or negedge rst_n) 18 begin 19 if(!rst_n) 20 begin 21 state<=s0; 22 z<=1'b0; 23 end 24 else 25 case(state) 26 s0:begin 27 if(x==1'b0) //0 28 begin 29 state<=s0; 30 z<=1'b0; 31 end 32 else //1 33 begin 34 state<=s1; 35 z<=1'b0; 36 end 37 end 38 s1:begin 39 if(x==1'b0) //10 40 begin 41 state<=s0; 42 z<=1'b0; 43 end 44 else //11 45 begin 46 state<=s2; 47 z<=1'b0; 48 end 49 end 50 s2:begin 51 if(x==1'b0) //110 52 begin 53 state<=s0; 54 z<=1'b0; 55 end 56 else //111 57 begin 58 state<=s3; 59 z<=1'b1; 60 end 61 end 62 s3:begin 63 if(x==1'b0) //1110 64 begin 65 state<=s0; 66 z<=1'b0; 67 end 68 else //1111 69 begin 70 state<=s3; 71 z<=1'b1; 72 end 73 end 74 default:begin 75 state<=s0; 76 z<=1'b0; 77 end 78 endcase 79 end 80 81 endmodule
(3) 111序列检测电路的测试代码如下:
//ex8_1 testbench //2020-10-13 // by YongFengXie `timescale 1ns/1ns module ex8_1tb; reg clk; reg rst_n; reg x; wire z; ex8_1 ut(clk,rst_n,x,z); initial begin clk=1'b0; rst_n=1'b0; x=1'b0; #40 rst_n=1'b1; #10 x=1'b0; #10 x=1'b0; #10 x=1'b1; #10 x=1'b0; #10 x=1'b1; #10 x=1'b1; #10 x=1'b0; #10 x=1'b1; #10 x=1'b1; #10 x=1'b1; #10 x=1'b0; #10 x=1'b1; #10 x=1'b1; #10 x=1'b1; #10 x=1'b1; #300 $stop; end always #5 clk=~clk; endmodule
(4) 111序列检测电路的ModelSim仿真结果如图ex8_1_1所示:
图ex8_1_1 111序列检测电路仿真结果
(5) 111序列检测电路FSM状态转换图如图ex8_1_2所示:
图ex8_1_2 111序列检测电路的状态转换图
(6)总结:书上的范例(王金明 《数字系统设计与Verilog HDL》)皆为序列检测电路,所以很容易模仿。FSM的写法3段,2段,1段。
感觉简单的电路,1段搞定,时序逻辑的状态转换,组合逻辑的电路输出, 可以用固定的套路或模板。状态机的设计主要难
点还是在于规划好有几个状态,然后就是顺理成章的转换和输出,有熟练的模板,就直接套用了。