[吾题有解] HDLBits : Exams/2013 q2bfsm

本题在状态机的实现上并不算复杂,只要能够通过题目描述画出状态转移图就能够得出标准的三段式状态机,只是其中有两个关键点需要特别注意,因而作此纪录,希望大家批评指正!

本题涉及两个关键点

  • 监视输入x的时机,即如何为输入x设置相关状态
  • 理解“在两个周期内输入y为1则……”这句话的实现

第一个关键点题中有多次指明:

  1. then after the next clock edge the FSM has to set the output f to 1 for one clock cycle. Then, the FSM has to monitor the x input.
  2. hint : The FSM does not begin to monitor the x input until the cycle after f is 1.

题目中称若复位则保持在A状态,取消复位后,将输出一个时钟周期的f = 1在这之后,才进入x的监视状态,这就说明:

  1. 需要一个状态来表示“输出了f = 1”,之后才进入x相关的状态,我们将这个状态称为“F”
  2. 对于x的序列判断,需要一个IDLE状态表示x的默认状态(或称首先接收到0的状态)而非直接从“F”状态判断输入x = 1进而判断x = 0,这样当x的输入序列不符合101需要跳回到某个状态重新开始时,就有了一个“立足点”。不使用“F”状态的原因是:F状态负责f的输出,如果跳回这个状态会导致f输出1,而f只在状态机脱离复位状态的下一个时钟周期上升沿输出1个时钟周期的1

第二个关键点在于:对于涉及次数的状态跳转,使用计数器还是直接将其化为状态本身?

我的观点是,如果转换后的状态不是很多,则优先采用转换为状态的方法。题目中的描述“在两个周期内若输入y = 1”很自然地联想到可以创建一个计数器对y的输入进行计数,但是在某些情况下这会带来计数器溢出的问题,如果再结合标志位,则会使原本描述简洁的状态机在形式上变得复杂。因此,将x接收到101序列后对输入y两周期内是否出现1的判断转化为相应的状态,得到状态转移图如下:
在这里插入图片描述
如图所示,当x输入序列101之后,g持续输出1,之后进入到输入y的判断中,如果y在第一个状态或者第二个状态跳转到“已经输入1”状态(Y_1),则g继续保持1输出,直到复位发生;若y时钟没有输入1,则先跳转到“第一次没有输入1”状态(Y_0)后跳转到“第二次没有输入1”状态(Y_00),此时g持续输出0,直到复位发生。

While maintaining g = 1 the FSM has to monitor the y input.…
But if y does not become 1 within two clock cycles, then the FSM should set g = 0 permanently (until reset).

因此,只要明白了以上两个关键点,此题的思路就不难分析。最后,给出本题的Verilog HDL:

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output f,
    output g
); 

    localparam A = 0, F = 1, X_IDLE = 2, X_1 = 3, X_10 = 4, X_101 = 5, Y_0 = 6, Y_1 = 7, Y_00 = 8;
    reg [3:0] state;
    reg [3:0] next_state;
    
    always @(posedge clk)
        if(~resetn)
            state <= A;
    	else
            state <= next_state;
    
    always @(*)
        case(state)
            A      : next_state =     F;
            F      : next_state =     X_IDLE;
            X_IDLE : next_state = x ? X_1   : X_IDLE;
            X_1    : next_state = x ? X_1   : X_10;
            X_10   : next_state = x ? X_101 : X_IDLE;
            X_101  : next_state = y ? Y_1   : Y_0;
            Y_1    : next_state =     Y_1;
            Y_0    : next_state = y ? Y_1   : Y_00;
            Y_00   : next_state =     Y_00;
        endcase
    
    assign f = state == F;
    assign g = state == X_101 || state == Y_0 || state == Y_1;
endmodule
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝莲花正开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值