** Verilog代码实现序列检测状态机学习记录
** //检测1100_1101 序列检测的核心就是状态机的画图实现,仔细分析各个状态的流向和最后一个状态的判断,如果最后一个状态会重复之前的序列,则回到符合的状态继续检测,否则返回到空闲状态重新检测序列,比如检测八位的1100—1101,第一个状态是空闲状态实际上是检测第一位1,如果为1检测第二位,否则在空闲状态继续检测,只要画出图,基本就完成了六七成。 上面的图片就是序列检测的状态机,照着这个图片写代码就很容易了。 源代码 module sequence_detection( input i_sys_clk , input i_sys_rst , input i_data , output o_result
); reg result = 0 ; reg [3:0] c_st = 0 ; reg [3:0] n_st = 0 ; parameter idle = 4'd0 ; parameter st0 = 4'd1 ; parameter st1 = 4'd2 ; parameter st2 = 4'd3 ; parameter st3 = 4'd4 ; parameter st4 = 4'd5 ; parameter st5 = 4'd6 ; parameter st6 = 4'd7 ; parameter st7 = 4'd8 ; assign o_result = result ; always @ (posedge i_sys_clk or posedge i_sys_rst) begin if(i_sys_rst) begin c_st <= idle ; end else begin c_st <= n_st ; end end always @ (*) begin case(c_st) idle : begin if(i_data) begin n_st <= st0 ; end else begin n_st <= idle ; end end st0 : begin if(i_data) begin n_st <= st1 ; end else begin n_st <= idle ; end end st1 : begin if(!i_data) begin n_st <= st2 ; end else begin n_st <= st1 ; end end st2 : begin if(!i_data) begin n_st <= st3 ; end else begin n_st <= st0 ; end end st3 : begin if(i_data) begin n_st <= st4 ; end else begin n_st <= idle ; end end st4 : begin if(i_data) begin n_st <= st5 ; end else begin n_st <= idle ; end end st5 : begin if(!i_data) begin n_st <= st6 ; end else begin n_st <= st1 ; end end st6 : begin if(i_data) begin n_st <= st7 ; end else begin n_st <= st3 ; end end st7 : begin if(i_data) begin n_st <= st1 ; end else begin n_st <= idle ; end end default : begin n_st <= idle ; end endcase end always @ (posedge i_sys_clk) begin if(n_st == st7) begin result <= 1'b1 ; end else begin result <= 1'b0 ; end end endmodule 测试代码 module sequence_tb(); reg i_sys_clk ; reg i_sys_rst ; wire i_data ; wire o_result ; reg [23:0] data = 24'd0 ; assign i_data = data[23] ; initial begin i_sys_clk = 0 ; i_sys_rst = 0 ; #100 i_sys_rst = 1; #100 i_sys_rst = 0; data = 24'b1100_1101_1001_1011_0101_1010; end always #10 i_sys_clk = ~i_sys_clk ; always @ (posedge i_sys_clk) begin data = {data[22:0],data[23]} ; endsequence_detection sequence_detection( .i_sys_clk (i_sys_clk ) , .i_sys_rst (i_sys_rst ) , .i_data (i_data ) , .o_result (o_result ) ); endmodule 下图是最终检测得到的波形图,当检测得到1100—1101时输出一个1.