Conor McCauley
Conor McCauley

Reputation: 135

Converting finite state machine diagram into verilog code

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.

fsm

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

Answers (2)

Oldfart
Oldfart

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

Greg
Greg

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

Related Questions