“10010”序列檢測器的Verilog實現與Modelsim模擬
阿新 • • 發佈:2019-01-24
序列檢測器是時序數位電路中非常常見的設計之一。它的主要功能是將一個指定的序列從數字碼流中識別出來。例如檢測器收到一組序列碼(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能檢測到序列的輸入並輸出高電平。