Reputation: 135
I've been trying to convert this Mealy finite state machine into Verilog code and it never manages to work for all combinations of states/inputs/etc.
Here is the Verilog code:
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
Upvotes: 0
Views: 1983
Reputation: 6259
If you look at the circuit and the state diagram you notice that the input to the state machine is a pure EXOR signal. Thus it is simplest to start with:
wire my_exor;
assign my_exor = x ^ y;
The next observation is that the output toggles each time the exor is true.
always @(posedge clk)
if (reset)
A <= 1'b0;
else if (my_exor)
A <= ~A;
Take the two together and you get Gregs code.
Upvotes: 1
Reputation: 19094
For the minimum change, the logic assignment to next
should be moved into an separate combinational block (always @*
). With next
as combinational, there is not need to give it an initial value. That should give you the behavior you expect.
Also note you have unnecessary logic. A
and state
are logically equivalent. Any reasonable synthesizer will merge them. Similarly, you expanded the xor logic into it's equivalent with logic operators. You could simply use the xor bit-wise operator (^
).
Case statements are common for state-machines. However they are not necessary when the state is encoded with two states. You could simplify and rewrite write the always
logic as:
always @(posedge clk) begin
if (reset_b) A <= 0;
else A <= A ^ x ^ y;
end
Upvotes: 2