1. 程式人生 > >“10010”序列檢測器的Verilog實現與Modelsim模擬

“10010”序列檢測器的Verilog實現與Modelsim模擬

      序列檢測器是時序數位電路中非常常見的設計之一。它的主要功能是將一個指定的序列從數字碼流中識別出來。例如檢測器收到一組序列碼(10010)後,輸出標誌1,否則,輸出0。

      本文引用自https://blog.csdn.net/llxxyy507/article/details/81019999

       在“10010”序列檢測器中,有6個狀態,加上一個Idle狀態,共7個狀態。但可以首先通過狀態化簡,簡少Verilog程式碼量。最初的狀態分析如下表。

      可以看到狀態“Idle”和狀態“0”,“10010”在相同的輸入下,下一狀態與輸出完全一樣,故可以化簡為一個狀態,所有狀態化簡後的對狀態進行命名,編碼。

                  

      對“Idle”,“1”,“10”,“100”,“1001”分別狀態命名為“Idle”,“S1”,“S10”,“S100”,“S1001”。Verilog程式如下:

module seq_detector(seq,clk,rst,b);       // detector "10010"
input seq,clk,rst;
output b; 

reg b;
reg [4:0]state;

parameter Idle  = 5'b1_0000,
          S1    = 5'b0_1000,
          S10   = 5'b0_0100,
          S100  = 5'b0_0010,
          S1001 = 5'b0_0001;

always @(posedge clk or negedge rst)     //low active
  if (!rst) begin
              state <= Idle;
              b <= 0;
             end
  else 
      case(state)
     Idle: if( seq == 0)
              begin
                state <= Idle;
                b <= 0;
              end
           else
              begin
                state <= S1;
                b <= 0;
              end
 
     S1: if( seq == 0)
              begin
                state <= S10;
                b <= 0;
              end
           else
              begin
                state <= S1;
                b <= 0;
              end

     S10: if( seq == 0)
              begin
                state <= S100;
                b <= 0;
              end
           else
              begin
                state <= S1;
                b <= 0;
              end

     S100: if( seq == 0)
              begin
                state <= Idle;
                b <= 0;
              end
           else
              begin
                state <= S1001;
                b <= 0;
              end

     S1001: if( seq == 0)
              begin
                state <= Idle;
                b <= 1;
              end
           else
              begin
                state <= S1;
                b <= 0;
              end
      
      default state <= 5'bx;
    endcase
endmodule

      testbench檔案如下:

`timescale 1ns/1ns
`define halfperiod 20

module t;
reg clk,rst;
reg [23:0]data;
wire seq,b;

assign seq = data[23];

initial
  begin
    clk = 0;
    rst = 1;
    #2 rst = 0;
    #30 rst = 1;
    data = 20'b1100_1001_0000_1001_0100;   //data為24位,但只給了20位,前面的會自動補零。
    #(`halfperiod * 1000)$stop;
  end

always #(`halfperiod) clk = ~clk;
always @(posedge clk)
         #2 data = {data[22:0],data[23]};

seq_detector m(.seq(seq), .clk(clk), .rst(rst), .b(b) );

endmodule

      通過Modelsim模擬得到的結果如下:

      可以看到seq在“10010”序列發生後,b能檢測到序列的輸入並輸出高電平。