最近在學習狀態機,用狀態機實現序列檢測器10010.
思路如下:
1. S0代表當前數據0,如果檢測到0就停在S0,如果檢測到1就進入S1。
2. S1代表當前數據1,如果檢測到0就進入S2,如果檢測到1就停在S1。
3. S2 代表數據10,如果檢測到0就進入S3,如果檢測到1就回到S1。
4. S3代表數據100,如果檢測到0就回到S0,如果檢測到1就進入S4。
5. S4代表數據1001,如果檢測到0就進入S5,如果檢測到1就回到S1。
6. S5代表數據10010,如果檢測到0就回到S0,如果檢測到1就進入S1。
狀態機圖如下:
代碼如下:
module Xulie( input wire clk, input wire rst_n, input wire in, output wire Bingo ); reg [5:0] state; parameter [5:0] S0 = 6'b00_0001; parameter [5:0] S1 = 6'b00_0010; parameter [5:0] S2 = 6'b00_0100; parameter [5:0] S3 = 6'b00_1000; parameter [5:0] S4 = 6'b01_0000; parameter [5:0] S5 = 6'b10_0000; always @ (posedge clk or rst_n) begin if(!rst_n) state <= S0; else case(state) S0: begin if(in == 1'b1) state <= S1; else state <= S0; end S1: begin if(in == 1'b0) state <= S2; else state <= S1; end S2: begin if(in == 1'b0) state <= S3; else state <= S1; end S3: begin if(in == 1'b1) state <= S4; else state <= S0; end S4: begin if(in == 1'b0) state <= S5; else state <= S1; end S5: begin if(in == 1'b0) state <= S0; else state <= S1; end default: state <= S0; endcase end assign Bingo = state == S5; endmodule
Testbench如下:
`timescale 1ns/1ns module Tb_Xulie; reg clk, rst_n,in; wire Bingo; initial begin clk = 0; rst_n = 0; in = 0; #100; rst_n =1; end initial begin #210; in = 1; #20; in = 1; #20; in = 0; #20; in = 0; #20; in = 1; #20; in = 0; #20; in = 1; #20; in = 1; #20; in = 0; #20; in = 1; #20; in = 0; #20; in = 0; #20; in = 1; #20; in = 0; #20; in = 1; end always #10 clk <= ~clk; Xulie Xulie_inst( .clk (clk), .rst_n (rst_n), .in (in), .Bingo (Bingo) ); endmodule
波形圖如下: