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

Converting finite state machine diagram into verilog code

我一直在尝试将这个 Mealy 有限状态机转换为 Verilog 代码,但它从未设法适用于 states/inputs/etc.

的所有组合

这是 Verilog 代码:

 1  `timescale 1ns/100ps
 2  `default_nettype none
 3  
 4  module OddFunction(
 5      output  reg     A,
 6      input   wire    x, y, clk, reset_b
 7  );
 8      
 9      parameter S0 = 1'b0, S1 = 1'b1;
10      
11      reg [1: 0] state, next;
12      initial next = S0;
13      
14      always @(posedge clk) begin
15          if (reset_b == 0) state <= S0;
16          else state <= next;
17          case (state)
18              S0: if ((x || y) && !(x && y)) next = S1; else next = S0;
19              S1: if (!((x || y) && !(x && y))) next = S0; else next = S1;
20          endcase
21          case (state)
22              S0: A = ((x || y) && !(x && y));
23              S1: A = !((x || y) && !(x && y));
24          endcase
25      end
26      
27  endmodule

对于最小的更改,next 的逻辑分配应移至单独的组合块 (always @*)。 next作为组合,不需要给它一个初始值。这应该会给你你期望的行为。

另请注意,您有不必要的逻辑。 Astate 在逻辑上是等价的。任何合理的合成器都会合并它们。同样,您将 xor 逻辑扩展为与逻辑运算符等效的逻辑。您可以简单地使用 xor bit-wise 运算符 (^)。

Case 语句在 state-machines 中很常见。然而,当状态用两个状态编码时,它们就不是必需的。您可以将 always 逻辑简化并重写为:

always @(posedge clk) begin
  if (reset_b) A <= 0;
  else         A <= A ^ x ^ y;
end

如果您查看电路和状态图,您会注意到状态机的输入是纯异或信号。因此最简单的开始是:

wire my_exor;
   assign my_exor = x ^ y;

下一个观察结果是每次异或为真时输出都会切换。

always @(posedge clk)
   if (reset)
      A <= 1'b0;
   else if (my_exor)
      A <= ~A;

把两者结合起来,你就得到了 Gregs 代码。