Search code examples
verilogfinite-automatastate-machine

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

Solution

  • 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