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段搞定,時序邏輯的狀態轉換,組合邏輯的電路輸出, 可以用固定的套路或模板。狀態機的設計主要難
點還是在於規划好有幾個狀態,然后就是順理成章的轉換和輸出,有熟練的模板,就直接套用了。