1. 項目介紹
序列檢測器是一種能夠檢測輸入的一串二進制代碼的電路,當該二進制代碼與事先設定的碼組一致時,檢測電路輸出高電平,否則輸出低電平。序列檢測器多用於通信系統中對同步碼的檢測,或者是對所需信號的提取,這在數字通信領域中有着廣泛的運用,如下圖所示101序列檢測器(可重疊)。

2. 設計要求
采用狀態機設計一個“1010110”序列檢測器,其功能是檢測到一個7位的二進制序列“1010110”,輸出一個時鍾周期的高脈沖,其他情況下為0。當遇到“…………1010110_10110……………..”時,后面的一個也認為滿足檢測要求。
3. 設計分析
序列檢測器檢測的關鍵在於正確碼的收到必須是連續的,這就要求檢測器必須記住前一次的正確碼及正確序列,直到在連續的檢測中所收到的每一位碼都與預置數的對應碼相同。在檢測過程中,任何一位不相同都將回到初始狀態重新開始檢測。
(1)系統架構圖

系統端口及其意義
- clk:系統時鍾,50MHz;
- rst_n: 系統復位信號,低電平有效;
- idata: 串行輸入信號
- flag:當檢測到 “1010110”,輸出一個時鍾周期的高脈沖,其他時刻為0;
(2)狀態划分
本系統采用狀態機進行設計,將“1010110”序列檢測過程划分為7個狀態:
- S0: 未檢測到有效信號的狀態;
- S1: 檢測到“1”信號;
- S2: 檢測到“10”信號;
- S3: 檢測到“101”信號;
- S4: 檢測到“1010”信號;
- S5: 檢測到“10101”信號;
- S6: 檢測到“101011”信號;

這里當遇到“…………1010110_10110……………..”時,后面的一個也認為滿足檢測要求,前面出現的信號可重復使用,會出現一個時鍾周期的高電平。
4. 設計實現
1 module sequence1010110( 2 input wire clk, 3 input wire rst_n, 4 input wire idata, 5 6 output reg flag 7 ); 8 9 localparam S0 = 7'b000_0001; 10 localparam S1 = 7'b000_0010; 11 localparam S2 = 7'b000_0100; 12 localparam S3 = 7'b000_1000; 13 localparam S4 = 7'b001_0000; 14 localparam S5 = 7'b010_0000; 15 localparam S6 = 7'b100_0000; 16 17 reg [6:0] c_state; 18 reg [6:0] n_state; 19 20 always@(posedge clk or negedge rst_n)begin 21 if(rst_n == 1'b0) 22 c_state <= S0; 23 else 24 c_state <= n_state; 25 end 26 27 always@(*)begin 28 case(c_state) 29 S0 : begin 30 if(idata == 1'b1) 31 n_state = S1; 32 else 33 n_state = S0; 34 end 35 36 S1: begin 37 if(idata == 1'b1) 38 n_state = S1; 39 else 40 n_state = S2; 41 end 42 43 S2: begin 44 if(idata == 1'b1) 45 n_state = S3; 46 else 47 n_state = S0; 48 end 49 50 S3: begin 51 if(idata == 1'b1) 52 n_state = S1; 53 else 54 n_state = S4; 55 end 56 57 S4: begin 58 if(idata == 1'b1) 59 n_state = S5; 60 else 61 n_state = S0; 62 end 63 64 S5: begin 65 if(idata == 1'b1) 66 n_state = S6; 67 else 68 n_state = S4; 69 end 70 71 S6: begin 72 if(idata == 1'b1) 73 n_state = S1; 74 else 75 n_state = S2; 76 end 77 78 default : n_state = S0; 79 endcase 80 end 81 82 always@(posedge clk or negedge rst_n)begin 83 if(rst_n == 1'b0) 84 flag <= 1'b0; 85 else 86 if((c_state == S6)&&(idata == 1'b0)) 87 flag <= 1'b1; 88 else 89 flag <= 1'b0; 90 91 end 92 93 endmodule
5. 仿真驗證
1 `timescale 1ns/1ps 2 3 module sequence1010110_tb(); 4 5 reg clk; 6 reg rst_n; 7 reg idata; 8 9 wire flag; 10 11 reg [15:0] ascii_state; 12 wire [6:0] tb_state; 13 14 assign tb_state = sequence1010110_inst.c_state; 15 16 always@(*)begin 17 case(tb_state) 18 7'b000_0001 : ascii_state = "S0"; 19 7'b000_0010 : ascii_state = "S1"; 20 7'b000_0100 : ascii_state = "S2"; 21 7'b000_1000 : ascii_state = "S3"; 22 7'b001_0000 : ascii_state = "S4"; 23 7'b010_0000 : ascii_state = "S5"; 24 7'b100_0000 : ascii_state = "S6"; 25 default : ascii_state = "NO"; 26 endcase 27 end 28 29 sequence1010110 sequence1010110_inst( 30 .clk (clk), 31 .rst_n (rst_n), 32 .idata (idata), 33 34 .flag (flag) 35 ); 36 37 initial clk = 1'b0; 38 always #10 clk = ~clk; 39 40 initial begin 41 rst_n = 1'b0; idata = 1'b0; 42 #101; 43 rst_n = 1'b1; 44 #50; 45 repeat(100)begin 46 @(posedge clk); #2; 47 idata = {$random}%2; 48 end 49 50 @(posedge clk); #2; idata = 1'b1; 51 @(posedge clk); #2; idata = 1'b0; 52 @(posedge clk); #2; idata = 1'b1; 53 @(posedge clk); #2; idata = 1'b0; 54 @(posedge clk); #2; idata = 1'b1; 55 @(posedge clk); #2; idata = 1'b1; 56 @(posedge clk); #2; idata = 1'b0; 57 @(posedge clk); #2; idata = 1'b1; 58 @(posedge clk); #2; idata = 1'b0; 59 @(posedge clk); #2; idata = 1'b1; 60 @(posedge clk); #2; idata = 1'b1; 61 @(posedge clk); #2; idata = 1'b0; 62 @(posedge clk); #2; idata = 1'b1; 63 @(posedge clk); #2; idata = 1'b1; 64 65 #200; $stop; 66 end 67 68 endmodule


6. 參考資料
