1、序列檢測器的邏輯功能描述:序列檢測指的就是將一個指定的序列從數字碼流中識別出來。本例中,我們將設計一個"10010”序列的檢測器。設x_in為數字碼流輸入,z_out為檢出標記輸出,高電平表示“發現指定序列”,低電平表示“沒有發現指定序列”。
2、本次試驗的data stream是 18'b11_0010_0100_0010_0101,通過循環來給x_in進行賦值。其中還要考慮到重疊現象。
3、重點是狀態圖的描繪,僅有當狀態機跳到E狀態時,z_out才置1,說明發現了指定序列。其實這個試驗關鍵是怎么來描繪該狀態機。第一次看到夏宇聞書上該例子時,腦子里馬上想到頭一個問題,就是他是如何畫出該狀態機的,這個過程沒有講,很納悶,那會是剛看Verilog,很多不懂,於是就放下這個問題,只閱讀了代碼。然而此次去看該例子時,我只看了題目和他的狀態機,代碼就不用看了,覺得書上畫的狀態機有點啰嗦,就沒仔細看,干脆自己畫一個 ,畫該狀態機其實也很簡單,先把所有狀態全都列出來,先單向的把IDLE->A->B->C->D->E跳變條件寫上,比如IDLE到A,是當輸入x_in為1時才會調到A,這個很好確認的吧,然后在仔細針對每個狀態為其它條件時該如何跳,比如B是在x_in為1時是到C的,那么就得好好考慮x_in為0時,狀態該跳到哪兒,就這樣一步一步的仔細推敲,完整的狀態機很快就完成。
4、代碼實現:
sequence_detect.v
1 module sequence_detect( 2 //input 3 clk, 4 rst_n, 5 x_in, 6 7 //ouput 8 z_out 9 ); 10 /****************************************/ 11 input clk; 12 input rst_n; 13 input x_in; 14 output z_out; 15 /****************************************/ 16 parameter IDLE = 3'd0; 17 parameter A = 3'd1; 18 parameter B = 3'd2; 19 parameter C = 3'd3; 20 parameter D = 3'd4; 21 parameter E = 3'd5; 22 /****************************************/ 23 reg [2:0] crt_state,nxt_state; 24 always @(posedge clk or negedge rst_n) 25 begin 26 if(!rst_n) 27 crt_state <= IDLE; 28 else 29 crt_state <= nxt_state; 30 end 31 /****************************************/ 32 always @(*) 33 begin 34 case(crt_state) 35 IDLE: if(x_in) nxt_state = A; 36 else nxt_state = IDLE; 37 38 A : if(!x_in) nxt_state = B; 39 else nxt_state = A; 40 41 B : if(!x_in) nxt_state = C; 42 else nxt_state = A; 43 44 C : if(x_in) nxt_state = D; 45 else nxt_state = IDLE; 46 47 D : if(!x_in) nxt_state = E; 48 else nxt_state = A; 49 50 E : if(!x_in) nxt_state = C; 51 else nxt_state = A; 52 53 default: nxt_state = IDLE; 54 endcase 55 end 56 /****************************************/ 57 reg z_out_temp; 58 always @(posedge clk or negedge rst_n) 59 begin 60 if(!rst_n) 61 z_out_temp <= 1'b0; 62 else case(nxt_state) 63 IDLE : z_out_temp <= 1'b0; 64 A : z_out_temp <= 1'b0; 65 B : z_out_temp <= 1'b0; 66 C : z_out_temp <= 1'b0; 67 D : z_out_temp <= 1'b0; 68 E : z_out_temp <= 1'b1; 69 default: z_out_temp <= 1'b0; 70 endcase 71 end 72 /****************************************/ 73 assign z_out = z_out_temp; 74 /****************************************/ 75 endmodule
sequence_detect_top.v
1 `timescale 1ns / 10ps 2 module sequence_detect_top; 3 reg clk; 4 reg rst_n; 5 reg [17:0] data; 6 wire x_in; 7 wire z_out; 8 /***********************************************************/ 9 initial 10 begin 11 clk = 1'b0; 12 rst_n = 1'b0; 13 #100; 14 rst_n = 1'b1; 15 end 16 /***********************************************************/ 17 always #10 clk = ~clk; 18 /***********************************************************/ 19 always @(posedge clk or negedge rst_n) 20 begin 21 if(!rst_n) 22 data <= 18'b11_0010_0100_0010_0101; 23 else 24 data <= {data[16:0],data[17]}; 25 end 26 /***********************************************************/ 27 assign x_in = data[17]; 28 /***********************************************************/ 29 sequence_detect sequence_detect_inst( 30 //input 31 .clk(clk), 32 .rst_n(rst_n), 33 .x_in(x_in), 34 35 //ouput 36 .z_out(z_out) 37 ); 38 /***********************************************************/ 39 endmodule
5、仿真波形:
僅當crt_state在E狀態(5)時,z_out置1。通過波形可以看到,輸出是正確的。