【3段式狀態機】— 序列檢測器(序列可重疊)


序列檢測器是個啥

檢測輸入的一串二進制代碼中,是否存在與事先設定的碼組一致的代碼串,檢測電路輸出高電平,否則輸出低電平

序列檢測器用在什么地方:

檢測通信系統中的同步碼、提取所需信號

要做的事:

使用狀態機檢測出一串數字序列中的指定6位數據:101011

 實踐:

S0:IDLE

S1:檢測1

S2:檢測10

S3:檢測101

S4:檢測1010

S5:檢測10101

S6:檢測101011

《關於狀態需要返回去東山再起》

  • 是否需要返回:不滿足檢測序列就需要返回
  • 前面幾位能用:有幾位滿足檢測序列順序
  • 自己能否作為起點:自己和序列第1 位相同就能作為起點

一、設計文件

module seq_1010110
(
input clk                    ,
input rst_n                    ,
input data                    ,

output reg flage
);

reg [2:0]state ;// 下面對狀態編碼用了1-7,所以這里需要用3位的位寬
reg [2:0]next_state;

parameter S0 = 3'd1;// IDLE 
parameter S1 = 3'd2;
parameter S2 = 3'd3;
parameter S3 = 3'd4;
parameter S4 = 3'd5;
parameter S5 = 3'd6;
parameter S6 = 3'd7;

always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)
    state <= S0;
else 
    state <= next_state;
end

always@(*)
    case(state)
        S0:
        if(data == 1)
            next_state <= S1;
        else 
            next_state <= S0;
        S1:
        if(data == 0)
            next_state <= S2;
        else 
            next_state <= S0;
        S2:
        if(data == 1)
            next_state <= S3;
        else 
            next_state <= S0;
        S3:
        if(data == 0)
            next_state <= S4;
        else 
            next_state <= S1;
        S4:
        if(data == 1)
            next_state <= S5;
        else 
            next_state <= S0;
        S5:
        if(data == 1)
            next_state <= S6;
        else 
            next_state <= S4;
        S6:
        if(data == 0)
            next_state <= S2;
        else 
            next_state <= S1;
        
    endcase 

always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)
    flage <= 1'b0;    
else if(state == S6 && data == 0) // Mealy狀態機:輸出由輸入和狀態共同決定   
    flage <= 1'b1;
else 
    flage <= 1'b0;        
end    

endmodule 

二、測試文件

`timescale 1ns/1ps

module sequence1010110_tb();
reg                            clk;
reg                            rst_n;
reg                            data;

wire                           flag;
reg             [15:0]        ascii_state;//用了2位字符S0-S6,1位字符8bit,所以這里位寬是16
wire             [2:0]            tb_state;

assign tb_state = seq_1010110_inst.state;

always@(*)begin // 在波形圖上能看到用S表示的狀態ascii_state
  case(tb_state)
        3'd1    :    ascii_state = "S0";
        3'd2    :    ascii_state = "S1";
        3'd3    :    ascii_state = "S2";
        3'd4    :    ascii_state = "S3";
        3'd5    :    ascii_state = "S4";
        3'd6    :    ascii_state = "S5";
        3'd7    :    ascii_state = "S6";
        default :  ascii_state = "NO";
  endcase
end

initial begin 
 
 clk = 1'b0;
 rst_n = 1'b0;
 data = 1'b0;
 #10;
 rst_n = 1'b1;
 end
 always #10 clk = ~ clk;
 
 
 always begin
 #20;
 data = 1'b1;
 #20;
 data = 1'b0;
  #20;
 data = 1'b1;
  #20;
 data = 1'b0;
  #20;
 data = 1'b1;
  #20;
 data = 1'b1;
  #20;
 data = 1'b0;
  #20;
 data = 1'b1;
 
 end

    seq_1010110 seq_1010110_inst(
        .clk                 (clk),
        .rst_n               (rst_n),
        .data                (data),

        .flage                    (flag)
    );

endmodule

三、波形圖

怎么看波形:

  • 重點看state和data,next_state只是用來給state傳遞數據的,可以不用重點看
  • 重點看flag在什么時候被拉高,除了要在時鍾上升沿,還需要注意是否需要比 (state == S6 && data == 0) 慢一拍

四、RTL圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM