基于Basys2的双序列检测器的设计(111000和101110)

一、设计要求(鲲鲲指定的就直接贴过来)

设计序列信号检测器:当输入码流为111000或101110时输出信号为1,否则输出0,然后对后续序列重新检测。如给定序列1011100010,输出只会拉高一次,对应红色序列段,而下划线序列段并不会使输出拉高。

从设计指标中可以得出,鲲鲲让我们做的是双序列都可以触发且非重复检测。

二、序列检测器原理

实际上并没有想象中的复杂,序列检测器的典型设计方法就是三段式状态机,不论是我们学过的静电1101序列检测器、10110序列检测器还是我们这次设计的双序列检测器,没有本质区别,不同的只是状态转移的状态数和转移的复杂度。

通过题目,我们就能得到以下状态转移图:(dot生成)

 dot源码

digraph Moore_FSM{
	bgcolor = "lavender";
	//起始状态
	IDLE[label = "IDLE",shape = "circle",style="",color="lightgoldenrod1"];
	//中间状态
	S0[label = "S0",shape = "circle",color="lime"];
	S1_1[label = "S1_1",shape = "circle",color="lime"];
	S2_1[label = "S2_1",shape = "circle",color="lime"];
	S3_1[label = "S3_1",shape = "circle",color="lime"];
	S4_1[label = "S4_1",shape = "circle",color="lime"];
	S1_2[label = "S1_2",shape = "circle",color="lime"];
	S2_2[label = "S2_2",shape = "circle",color="lime"];
	S3_2[label = "S3_2",shape = "circle",color="lime"];
	S4_2[label = "S4_2",shape = "circle",color="lime"];
	//输出结果
	TEST[label = "TEST",shape = "circle",color="seagreen1"];
	//开始连线
	IDLE -> S0[label = "1/0"];
	IDLE -> IDLE[label = "0/0"];

	S0 -> S1_1[label = "1/0"];
	S0 -> S1_2[label = "0/0"];

	S1_1 -> S2_1[label = "1/0"];
	S1_1 -> S1_2[label = "0/0"];

	S2_1 -> S3_1[label = "0/0"];
	S2_1 -> S1_1[label = "1/0"];

	S3_1 -> S4_1[label = "0/0"];
	S3_1 -> S2_2[label = "1/0"];

	S4_1 -> TEST[label = "0/0"];
	S4_1 -> S0[label = "1/0"];

	S1_2 -> S2_2[label = "1/0"];
	S1_2 -> IDLE[label = "0/0"];

	S2_2 -> S3_2[label = "1/0"];
	S2_2 -> S1_2[label = "0/0"];

	S3_2 -> S4_2[label = "1/0"];
	S3_2 -> IDLE[label = "0/0"];

	S4_2 -> TEST[label = "0/0"];
	S4_2 -> S2_1[label = "1/0"];

	TEST -> IDLE[label = "/1"];
}

三、Verilog实现与仿真

1、Verilog代码:

应用三段式状态机思想,状态机由状态寄存器、状态转移逻辑、输出控制逻辑组成,具体代码如下:

module seq_dector(
    input clk,
    input rst_n,
    input data_in,
    output reg data_out
    );
    //定义状态寄存器
    reg [10:0]current_state,next_state;
    //状态定义:独热码
    parameter IDLE = 11'b00000000001;
    parameter S0   = 11'b00000000010;
    parameter S1_1 = 11'b00000000100;
    parameter S1_2 = 11'b00000001000;
    parameter S2_1 = 11'b00000010000;
    parameter S2_2 = 11'b00000100000;
    parameter S3_1 = 11'b00001000000;
    parameter S3_2 = 11'b00010000000;
    parameter S4_1 = 11'b00100000000;
    parameter S4_2 = 11'b01000000000;
    parameter TEST = 11'b10000000000;
    //同步时序逻辑控制状态的切换
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            current_state <= IDLE;
        else
            current_state <= next_state;
    end
    //组合逻辑判断状态转移条件
    always@(*)
    begin
        if(!rst_n)
        begin
            next_state = IDLE;
        end
        else
        begin
            case(current_state)
                IDLE:
                begin
                    if(data_in == 1'b1)
                        next_state = S0;
                    else 
                        next_state = IDLE;
                end
                S0:
                begin
                    if(data_in == 1'b1)
                        next_state = S1_1;
                    else 
                        next_state = S1_2;
                end
                S1_1:
                begin
                    if(data_in == 1'b1)
                        next_state = S2_1;
                    else 
                        next_state = S1_2;
                end
                S1_2:
                begin
                    if(data_in == 1'b1)
                        next_state = S2_2;
                    else 
                        next_state = IDLE;
                end
                S2_1:
                begin
                    if(data_in == 1'b0)
                        next_state = S3_1;
                    else 
                        next_state = S2_2;
                end
                S2_2:
                begin
                    if(data_in == 1'b1)
                        next_state = S3_2;
                    else 
                        next_state = S1_2;
                end
                S3_1:
                begin
                    if(data_in == 1'b0)
                        next_state = S4_1;
                    else 
                        next_state = S2_2;
                end
                S3_2:
                begin
                    if(data_in == 1'b1)
                        next_state = S4_2;
                    else 
                        next_state = IDLE;
                end
                S4_1:
                begin
                    if(data_in == 1'b0)
                        next_state = TEST;
                    else 
                        next_state = IDLE;
                end
                S4_2:
                begin
                    if(data_in == 1'b0)
                        next_state = TEST;
                    else 
                        next_state = S2_1;
                end
                TEST:
                begin
                    next_state = IDLE;
                end
            endcase
        end
    end
    //同步逻辑描述状态的输出
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            data_out <= 1'b0;
        end
        else
        begin
            if(next_state == TEST)
                data_out <= 1'b1;
            else
                data_out <= 1'b0;
        end
    end
    
endmodule

2、testbench

module testbench;

	// Inputs
	reg clk;
	reg rst_n;
	reg data_in;

	// Outputs
	wire data_out;

	// Instantiate the Unit Under Test (UUT)
	seq_dector uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.data_in(data_in), 
		.data_out(data_out)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		rst_n = 0;
		data_in = 0;

		// Wait 100 ns for global reset to finish
		#20;
        rst_n = 1'b1;
		// Add stimulus here
        data_in = 1'b0;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b0;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b1;
        #20
        data_in = 1'b0;
        $finish;
	end
    always #10 clk = ~clk;
endmodule

3、仿真结果

设计测试激励序列:0-101110_00-111000-101110

理论上结果:      00000000100000000010000001

仿真结果:

由于状态机由上升沿触发,所以从上图可以看出:在第一个有效序列101110到来的时候,在上升沿的时刻输出信号1,持续到下一个时钟上升沿。后来的111000和101110也是如此。

并且完成了非重复性检测的要求,序列检测器在遇到10111000的时候只产生一次检测信号。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值