当前位置:   article > 正文

HDLBits刷题(Building Larger Circuits)_实现一个状态机,构建一个有限状态机,在输入位流中搜索序列1101。当找到序列时,它

实现一个状态机,构建一个有限状态机,在输入位流中搜索序列1101。当找到序列时,它

3.3.1 Counter with period 1000
问题陈述:

建立一个从0到999的计数器,包括0到999,周期为1000个周期。复位输入是同步的,应将计数器复位0.
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,
    output [9:0] q);
    always @(posedge clk)
        begin
            if(reset)
                q<=0;
            else if(q==999)
                q<=0;
            else
                q<=q+1'b1;
        end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.3.2 4-bit shift register and down counter
问题陈述:

构建一个四位移位寄存器,该寄存器也用作递减计数器。当shift_ena为1时,数据首先移入最高有效位。当count_ena为1时当前在移位寄存器中的数字递减。由于整个系统不会同时使用shift_ena和counter_ena,因此您的电路无关紧要如果两个控制输入都为1(这主要意味着,哪种情况获得更高优先级并不重要)。
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output [3:0] q);
    always@(posedge clk)
        begin
            if(shift_ena)
                begin
                q[0]<=data;
            q[1]<=q[0];
            q[2]<=q[1];
            q[3]<=q[2];
                end
            else if(count_ena)
                q[3:0]<=q[3:0]-1'b1;
            else
                q<=q;
        end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3.3.3 FSM:Sequence 1101 recognizer
问题陈述:

构建一个有限状态机,在输入比特流中搜索序列1101.找到序列后,应将start_shifting设置为1,直到重置。陷入最终状态旨在模拟在尚未实现的更大FSM中进入其他状态。我们将在接下来的几个练习中扩展这个FSM。
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
    parameter s0=0,s1=1,s2=2,s3=3,s4=4,END=5;
    reg[3:0]state,next;
    always@(posedge clk)
        begin
            if(reset)
                state<=s0;
            else
                state<=next;
        end
    always@(*)
        begin
            case(state)
                s0:next=data?s1:s0;
                s1:next=data?s2:s0;
                s2:next=data?s2:s3;
                s3:next=data?s4:s0;
                s4:next=s4;
                default:next=s0;
            endcase
        end
    always@(posedge clk)
        begin
            if(reset)
                start_shifting<=1'b0;
            else if(next==s4)
                start_shifting<=1'b1;
        end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

3.3.4 FSM:Enable shift register
问题陈述:

作为用于控制移位寄存器的FSM的一部分,我们希望能够在检测到正确的位模式的移位寄存器恰好4个周期。FSM的这一部分仅处理启用4个周期的移位寄存器。
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    reg[3:0] counter;
    always@(posedge clk)
        begin
            if(reset)
                counter<=4'd0;
            else if(shift_ena)
                begin
                    if(counter==4'd3)
                        counter<=4'd0;
                    else
                        counter<=counter+1'b1;
                end
        end
    always@(posedge clk)
        begin
            if(reset)
                shift_ena<=1'b1;
            else if((shift_ena==1'b1)&&(counter==4'd3))begin
                    shift_ena<=1'b0;
                    end
                    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

3.3.5 FSM:The complete FSM
问题陈述:

我们想创建一个带有输入的计时器:
1.在检测到特定模式(1101)时启动
2.再平移4位来决定延迟的时间,
3.等计数器数完,然后
4.通知用户并等待用户确认计时器。

在这个问题中,只实现控制计时器的有限状态机。此处不包括数据路径(计数器和一些比较器)。
串行数据在数据输入引脚上可用。当接收到模式1101时,状态机必须在4个时钟周期内断言输出shift_ena。

在此之后,状态机断言其计数输出,以指示它正在等待计数器,并等待直到输入done_counting为高值。

此时,状态机必须断言done以通知用户计时器已超时,并等待直到输入ack为1,然后重置以查找开始序列(1101)的下一个出现。

状态机应该重置为开始搜索输入序列1101的状态。

下面是预期输入和输出的示例。“x”状态可能读起来有点混乱。它们表明FSM不应该关心该周期中特定的输入信号。例如,一旦检测到1101模式,FSM就不再查看数据输入,直到完成所有其他工作后才恢复搜索。
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output shift_ena,
    output counting,
    input done_counting,
    output done,
    input ack );
	parameter s0=0,s1=1,s2=2,s3=3,s4=4,b1=5,b2=6,b3=7,counter=8,WAIT_T=9;
    reg[3:0]state,next;
    always@(posedge clk)
        begin
            if(reset)
                state<=s0;
            else 
                state<=next;
        end
    always@(*)
        begin
            case(state)
                s0:next=data?s1:s0;
                s1:next=data?s2:s0;
                s2:next=data?s2:s3;
                s3:next=data?s4:s0;
                s4:next=b1;
                b1:next=b2;
                b2:next=b3;
                b3:next=counter;
                counter:next=done_counting?WAIT_T:counter;
                WAIT_T:next=ack?s0:WAIT_T;
            endcase
        end
    assign shift_ena=((state==s4)||(state==b1)||(state==b2)||(state==b3));
    assign counting=(state==counter);
    assign done=(state==WAIT_T);
                
                    
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

3.3.6 The complete timer
问题陈述:

我们想创建一个带有一个输入的计时器:

1.当检测到特定输入模式 (1101) 时启动
2.再移 4 位以确定延迟的持续时间
3.等待计数器完成计数
4.并且 通知用户并等待用户确认计时器。
串行数据在数据输入引脚上可用。当接收到模式1101时,电路必须移位接下来的4位,首先最高有效位。这4位决定了定时器延迟的持续时间。将此称为delay[3:0]。
之后,状态机断言其计数输出,以指示它正在计数。状态机必须精确计算(delay[3:0]+ 1)* 1000个时钟周期。例如,delay=0表示计数1000个循环,delay=5表示计数6000个周期。同时输出当前剩余时间。这应该等于1000个周期的延迟,然后1000个周期的延迟-1,以此类推,1000个周期的延迟是0。当电路不计数时,count[3:0]输出是不关心的(任何值对你来说是方便实现的)。
此时,电路必须断言done来通知用户计时器已经超时,并等待直到输入ack为1,然后重置以寻找开始序列(1101)的下一个出现。
电路应该重置到开始搜索输入序列1101的状态。
下面是预期输入和输出的示例。“x”状态可能读起来有点混乱。它们表明FSM不应该关心该周期中特定的输入信号。例如,一旦读取了1101和delay[3:0],电路就不再查看输入的数据,直到在所有其他事情都完成后才恢复搜索。在本例中,电路计数为2000个时钟周期,因为delay[3:0]值为4’b0001。最后几个循环开始另一个计数,延迟[3:0]= 4’b1110,这将计数15000个循环。请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );
	parameter IDLE=4'd0,s1=4'd1,s11=4'd2,s110=4'd3,b0=4'd4,b1=4'd5,b2=4'd6,b3=4'd7,Count=4'd8,WAIT=4'd9;
    reg[3:0] state,next;
    reg[3:0] delay;
    reg[15:0]counter;
    reg[3:0]temp;
    wire done_counting;
    
    always@(posedge clk)begin
        if(reset) begin
            state<=IDLE;
        end
        else
            state<=next;
    end
    
    always@(posedge clk) begin
        if(reset) 
            counter<=16'd0;
        else if(next==WAIT)
            counter<=16'd0;
        else if(next==Count)
            counter<=counter+1'b1;

    end
    
        always @(*) begin
            if(counter<=16'd1000)
                temp=4'd0;
            else if(counter==16'd2000)
                temp=4'd1;
            else if(counter==16'd3000)
                temp=4'd2;
            else if(counter==16'd4000)
                temp=4'd3;
            else if(counter==16'd5000)
                temp=4'd4;
            else if(counter==16'd6000)
                temp=4'd5;
            else if(counter==16'd7000)
                temp=4'd6;
            else if(counter==16'd8000)
                temp=4'd7;
            else if(counter==16'd9000)
                temp=4'd8;
            else if(counter==16'd10000)
                temp=4'd9;
            else if(counter==16'd11000)
                temp=4'd10;
            else if(counter==16'd12000)
                temp=4'd11;
            else if(counter==16'd13000)
                temp=4'd12;
            else if(counter==16'd14000)
                temp=4'd13;
            else if(counter==16'd15000)
                temp=4'd14;
            else
                temp=4'd15;
        end
    
    assign done_counting=((state==Count)&(counter==(delay+1)*1000))?1'b1:1'b0;
    
	always@(*) begin
        case(state)
            IDLE: next=data? s1:IDLE;
            s1  : next=data? s11:IDLE;
            s11 : next=data? s11:s110;
            s110: next=data? b0:IDLE;
            b0  : begin
                next=b1; delay[3]=data;
            end
            b1: begin
                next=b2; delay[2]=data;
            end
            b2: begin
                next=b3; delay[1]=data;
            end
            b3:begin 
                next=Count; delay[0]=data;
            end
            Count:next=done_counting?WAIT:Count;
            WAIT :next=ack?IDLE:WAIT;
            endcase
        end
    assign count=(state==Count)?(delay-temp):4'd0;
            assign counting=(state==Count);
             assign done=(state==WAIT);

                              
            
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99

3.3.7 FSM: One-hot logic equation
问题陈述:

给定一下具有3个输入、3个输出、10个状态的状态机:
在这里插入图片描述
假设使用以下one-hot编码,通过检查导出下一个状态逻辑方程好人输出逻辑方程:(S, S1, S11, S110, B0, B1, B2, B3, Count, Wait) = (10’b0000000001, 10’b0000000010, 10’b0000000100, … , 10’b1000000000)
假设one-hot编码,通过检查导出状态转换和输出逻辑方程。仅实现此状态机的状态转换和输出逻辑方程。仅实现此状态转换(组合逻辑部分)。(测试台将使用非一个热输入进行测试,以确保您不会尝试复杂的事情)。
编写上次以下等式代码:

  • List item
  • B3_next – next-state logic for state B3
  • S_next
  • S1_next
  • Count_next
  • Wait_next
  • done – output logic
  • counting

Verilog代码:

module top_module(
    input d,
    input done_counting,
    input ack,
    input [9:0] state,    // 10-bit one-hot current state
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
); //

    // You may use these parameters to access state bits using e.g., state[B2] instead of state[6].
    parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;

    // assign B3_next = ...;
    // assign S_next = ...;
    // etc.
    assign B3_next=(state[B2]);
    assign S_next=(~d&(state[S]|state[S1]|state[S110])|(ack&state[Wait]));
    assign S1_next=(d&state[S]);
    assign Count_next=(state[B3]|(state[Count]&~done_counting));
    assign Wait_next=((state[Count]&done_counting)|(state[Wait]&~ack));
    assign counting=(state[Count]);
    assign done=(state[Wait]);
    assign shift_ena=(state[B0]|state[B1]|state[B2]|state[B3]);
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/648809
推荐阅读
相关标签
  

闽ICP备14008679号