我一直在尝试将这个Mealy有限状态机转换为Verilog代码,并且它永远不会适用于状态/输入/等的所有组合。
以下是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
答案 0 :(得分:1)
对于最小的更改,应将next
的逻辑分配移动到单独的组合块(always @*
)中。将next
作为组合,不需要给它初始值。这应该会给你你期望的行为。
另请注意,您有不必要的逻辑。 A
和state
在逻辑上是等效的。任何合理的合成器都会合并它们。类似地,您将xor逻辑扩展为与逻辑运算符等效的逻辑。您可以简单地使用xor位智能运算符(^
)。
案例陈述对于状态机来说很常见。但是,当状态用两种状态编码时,它们不是必需的。您可以简化并重写将always
逻辑写为:
always @(posedge clk) begin
if (reset_b) A <= 0;
else A <= A ^ x ^ y;
end
答案 1 :(得分:1)
如果查看电路和状态图,您会注意到状态机的输入是纯EXOR信号。因此,最简单的方法是:
wire my_exor;
assign my_exor = x ^ y;
下一个观察是每次exor为真时输出都会切换。
always @(posedge clk)
if (reset)
A <= 1'b0;
else if (my_exor)
A <= ~A;
将两者放在一起,你得到Gregs代码。