FPGA序列检测状态机(四段式)

本文介绍了如何使用VerilogHDL语言设计并实现一个检测特定序列(如“01101”)的时序数字电路,包括状态转换图的绘制、信号定义、RTL编码以及编写测试代码进行VCS仿真,验证了电路在给定输入序列下的正确工作行为。
摘要由CSDN通过智能技术生成

编码仿真作业题250分

完成一个序列检测器101011011的序列检测,完成RTL编程,完成testbench的编写,并利用VCS进行仿真。

序列检测器是时序数字电路中非常常见的设计之一。它的主要功能是:将一个指定的序列从数字码流中识别出来。接下来就以设计“01101”这个序列的检测器为例,说明Verilog HDL语言的具体应用。设X为数字码流输入,Z为检出标记输出,高电平表示“发现指定序列”,低电平表示“没有发现指定的序列”。设输入的码流为“001101101111011111...”,在时钟2~6中,码流X里出现指定序列“01101”,对应输出Z在第6个时钟变为高电平“1”,表示发现指定"01101”,Z输出“1”。同理在第9个时钟对应输出Z也为“1”。

1、画出状态转换图

2、定义信号和位宽

3、编写序列检测状态机RTL编码

module homework_8_2(
    clk     ,
    rst_n   ,
    din     ,
    dout    ,
);

input   clk         ;
input   rst_n       ;
input   din         ;
output  dout        ;

reg     dout        ;
reg [3:0]state_c    ;
reg [3:0]state_n    ;

wire s02s1_start ;
wire s12s2_start ;
wire s22s0_start ;
wire s22s3_start ;
wire s32s4_start ;
wire s32s1_start ;
wire s42s0_start ;
wire s42s5_start ;
wire s52s4_start ;
wire s52s6_start ;
wire s62s7_start ;
wire s62s1_start ;
wire s72s0_start ;
wire s72s8_start ;
wire s82s4_start ;
wire s82s0_start ;




parameter   S0 = 0;
parameter   S1 = 1;
parameter   S2 = 2;
parameter   S3 = 3;
parameter   S4 = 4;
parameter   S5 = 5;
parameter   S6 = 6;
parameter   S7 = 7;
parameter   S8 = 8;


//四段式状态机

//第一段:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器(不需更改)
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        state_c <= S0;
    end
    else begin
        state_c <= state_n;
    end
end

//第二段:组合逻辑always模块,描述状态转移条件判断
always @(*)begin
    case(state_c)
        S0:begin
            if(s02s1_start)begin
                state_n = S1;
            end
            else begin
                state_n = state_c;
            end
        end
        S1:begin
            if(s12s2_start)begin
                state_n = S2;
            end
            else begin
                state_n =state_c;
            end
        end
        S2:begin
            if(s22s0_start)begin
                state_n = S0;
            end
            else if(s22s3_start)begin
                state_n = S3;
            end
            else begin
                state_n =state_c;
            end
        end
        S3:begin
            if(s32s4_start)begin
                state_n = S4;
            end
            else if(s32s1_start)begin
                state_n = S1;
            end
            else begin
                state_n =state_c;
            end
        end
        S4:begin
            if(s42s0_start)begin
                state_n = S0;
            end
            else if(s42s5_start)begin
                state_n = S5;
            end
            else begin
                state_n =state_c;
            end
        end
        S5:begin
            if(s52s4_start)begin
                state_n = S4;
            end
            else if(s52s6_start)begin
                state_n = S6;
            end
            else begin
                state_n =state_c;
            end
        end
        S6:begin
            if(s62s7_start)begin
                state_n = S7;
            end
            else if(s62s1_start)begin
                state_n = S1;
            end
            else begin
                state_n =state_c;
            end
        end
        S7:begin
            if(s72s0_start)begin
                state_n = S0;
            end
            else if(s72s8_start)begin
                state_n = S8;
            end
            else begin
                state_n =state_c;
            end
        end
        S8:begin
            if(s82s4_start)begin
                state_n = S4;
            end
            else if(s82s0_start)begin
                state_n = S0;
            end
            else begin
                state_n =state_c;
            end
        end
        default:begin
            state_n =S0;
        end
    endcase
end

//第三段:设计转移条件
//assign s02s0_start = state_c ==S0 && din==0 ;
assign s02s1_start = state_c ==S0 && din==1 ;
//assign s12s1_start = state_c ==S1 && din==1 ;
assign s12s2_start = state_c ==S1 && din==0 ;
assign s22s0_start = state_c ==S2 && din==0 ;
assign s22s3_start = state_c ==S2 && din==1 ;
assign s32s4_start = state_c ==S3 && din==0 ;
assign s32s1_start = state_c ==S3 && din==1 ;
assign s42s0_start = state_c ==S4 && din==0 ;
assign s42s5_start = state_c ==S4 && din==1 ;
assign s52s4_start = state_c ==S5 && din==0 ;
assign s52s6_start = state_c ==S5 && din==1 ;
assign s62s7_start = state_c ==S6 && din==0 ;
assign s62s1_start = state_c ==S6 && din==1 ;
assign s72s0_start = state_c ==S7 && din==0 ;
assign s72s8_start = state_c ==S7 && din==1 ;
assign s82s4_start = state_c ==S8 && din==0 ;
assign s82s0_start = state_c ==S8 && din==1 ;

//第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出)
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 0)begin
        dout <= 0;
    end
    else if(state_c ==S8 && din==1 )begin
        dout <= 1;
    end
    else begin
        dout <= 0;
    end
end

endmodule

4、编写测试代码

`timescale 1 ns/ 1 ns

module tb_homework_8_2();

reg  clk    ;
reg  rst_n  ;
reg  din    ;
wire dout   ;

parameter CYCLE = 20;
parameter RST_TIME = 3;

homework_8_2 uut(
    .clk    (clk    ),
    .rst_n  (rst_n  ),
    .din    (din    ),
    .dout   (dout   )
);

initial begin
    clk = 0;
    forever
    #(CYCLE/2)
    clk = ~clk;
end

initial begin
    rst_n = 1;
    #2;
    rst_n = 0;
    #(CYCLE*RST_TIME);
    rst_n = 1;
end

initial begin
    #1;
    din = 0;
    #(CYCLE*10);
    din = 1;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
    din = 1;
    #(CYCLE);
    din = 0;
    #(CYCLE);
end
endmodule

这里简单的进行了测试,测试了一组101011011序列。

5、VCS仿真

通过VCS仿真,我们发现,在状态S8到达,并din为1时,状态跳转为状态S0,且dout拉高为1,符合实验预期。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值