来自 HDLBits 的 FSM 问题的输出与预期不同

FSM question from HDLBits has different output than expected

问题:- 考虑用于控制某种类型电机的有限状态机。 FSM 具有来自电机的输入 x 和 y,并产生控制电机的输出 f 和 g。还有一个称为 clk 的时钟输入和一个称为 resetn 的复位输入。

FSM 必须按如下方式工作。只要复位输入有效,FSM 就会保持初始状态,称为状态 A。当复位信号无效时,在下一个时钟边沿之后,FSM 必须将输出 f 设置为 1,持续一个时钟周期.然后,FSM 必须监控 x 输入。当 x 在三个连续的时钟周期中产生值 1、0、1 时,则应在下一个时钟周期将 g 设置为 1。在保持 g = 1 的同时,FSM 必须监控 y 输入。如果 y 在最多两个时钟周期内具有值 1,则 FSM 应永久保持 g = 1(即,直到重置)。但是如果y在两个时钟周期内没有变为1,那么FSM应该永久设置g = 0(直到重置)。

(原题只要求状态图,这里实现FSM)

我的代码:

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output f,
    output g
); 
    parameter a=0,b=1,c=2,d=3,e=4,f1=5,g1=6,h=7,i=8,per=9;
    reg [3:0] state,ns;
    always@(posedge clk) begin
        if(~resetn)
            ns<=a;
        case(state)
            a:ns<=resetn ? b : a;
            b:ns<=c;
            c:ns<=x ? d : c;
            d:ns<=x ? d : e;
            e:ns<=x ? f1 : d;
            f1:ns<=y ? per : g1;
            g1:ns<=y ? per : i;
            per:ns<=resetn ? per : a;
            i:ns<=resetn ? i : a;
        endcase
    end
    assign state=ns;
    assign f=(state==b);
    assign g=(state==f1|state==g1|state==per);
endmodule

您的重置逻辑有问题。您应该将重置子句与其余逻辑分开;它应该只包含在 if 子句中,而不应该包含在 case 语句中。

此外,case 语句应该在 else 子句中:

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output f,
    output g
); 
    parameter a=0,b=1,c=2,d=3,e=4,f1=5,g1=6,h=7,i=8,per=9;
    reg [3:0] state;
    always@(posedge clk) begin
        if (~resetn) begin
            state<=a;
        end else begin
            case(state)
                a:state<=b;
                b:state<=c;
                c:state<=x ? d : c;
                d:state<=x ? d : e;
                e:state<=x ? f1 : d;
                f1:state<=y ? per : g1;
                g1:state<=y ? per : i;
            endcase
        end
    end
    assign f=(state==b);
    assign g=(state==f1|state==g1|state==per);
endmodule

不需要有2个状态变量。我更改了 FSM,使其只保留 state.