将有限状态机图转换为Verilog代码

时间:2018-03-21 21:05:50

标签: verilog finite-automata state-machine

我需要将以下有限状态图转换为Verilog代码。 enter image description here

我已经包含了我到目前为止编写的代码。在我看来,我已经正确地实现了所有逻辑,并且代码适用于前几个输入组合。它最终失败了,我似乎无法弄清楚原因。

module FiniteStateMachine(output reg out_z, input in_x, in_y, clk, reset_b);

    parameter   S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
    reg         state;

    always @(posedge clk, negedge reset_b) begin

        // set state
        if (reset_b || !in_x) state <= S0;
        else
            case (state)
                S0: state <= (in_y == 1) ? S1 : S3;
                S1: state <= S2;
                S2: state <= S3;
                S3: state <= S3;
            endcase

        // set output
        out_z <= (state == S2 || state == S3) ? 1 : 0;

    end

endmodule

2 个答案:

答案 0 :(得分:1)

看起来您已尝试通过将in_x视为辅助重置来简化FSM。我不认为这种简化是正确的,无论如何你都试图过于聪明。只需写出每个案例的所有转换,可以是嵌套的case语句,也可以是每个状态下的一系列if。例如:

case (state)
  S0: case ({in_x, in_y})
    2'b00: state <= S0;
    2'b01: state <= S0;
    2'b10: state <= S3;
    2'b11: state <= S1;
  endcase
  S2: case ({in_x, in_y})
    …

答案 1 :(得分:1)

现在,您的实施存在许多问题:

  1. state变量需要为2时,reg state变量只有一位宽:reg [1:0] state - &gt; out_z
  2. 你可能真的不希望reset_b成为一个寄存器,因为它应该在同一个时钟上跟随状态,而不是之后的时钟周期。
  3. 您的!reset_b逻辑向后,对于negedge重置,您需要通过~reset_breset_b检查断言。
  4. 正如已经提到的,你不应该像使用in_xmodule FiniteStateMachine(output reg out_z, input in_x, in_y, clk, reset_b); parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11; reg [1:0] state; // Fix state variable // Set output combinationally (no need for turning operator) always @(*) begin out_z = (state == S2 || state == S3); end always @(posedge clk, negedge reset_b) begin // Invert the logic for reset and keep it separate if (!reset_b) begin state <= S0; end else begin // You can case on inputs as was suggested, but I think casing on state is fine // I include only logic for changing state case (state) S0: begin if (in_x && in_y) begin state <= S1; end else if (in_x && !in_y) begin state <= S3; end end S1: begin if (in_x) begin state <= S2; end else begin state <= S0; end end S2: begin if (in_x) begin state <= S3; end else begin state <= S0; end end S3: begin if (!in_x) begin state <= S0; end end endcase end end endmodule 那样将异步复位与任何同步输入相结合,甚至是同步复位。虽然这在模拟中可以正常工作,但大多数综合工具可能无法正确处理它。在学习Verilog时,我犯了同样的错误,需要花费数天才能发现并纠正。
  5. 这是一个更清晰的代码版本,实现了此修补程序并进行了评论,因此您可以看到以下4点:

    with open('file.xml', 'rt', encoding='utf8') as file:
        for line in file.readline():
            do_something(line)