Search code examples
arraysverilogsystem-verilogstate-machineiverilog

Implement a state machine in Verilog using a 2D array as transition table


I'm trying to implement a very simple Mealy state machine in Verilog. I have already done it with case and if statements, but I want to be able to do the same using a 2D array as transition table, for clarity.

Here is the code:

module ex10_1_2(
  // output
  output reg o,
  
  // debug output to see the current state
  output [1:0] s,
  
  // input, clk signal
  input i, clk);
  
  // states
  localparam A = 2'b00, B=2'b01, C = 2'b10, D = 2'b11;
  
  // transition table
  reg [3:0] ttable [1:0][2:0];
  
  // current state
  reg [1:0] cs;
  
  initial begin
    
    // initial values: state A, output 0.
    cs <= A;
    o <= 0;
    
    // curr. state|input|next st.|output
    ttable[A][0] = {B, 1'b0};
    ttable[A][1] = {A, 1'b1};
    ttable[B][0] = {C, 1'b1};
    ttable[B][1] = {A, 1'b0};
    ttable[C][0] = {D, 1'b0};
    ttable[C][1] = {C, 1'b0};
    ttable[D][0] = {A, 1'b1};
    ttable[D][1] = {C, 1'b0};
  end
  
  always @ (posedge clk)
    begin
      cs <= ttable[cs][i][2:1];
      o <= ttable[cs][i][0];
    end
  
  assign s = cs;
  
endmodule

As you can see, the transition table is 4 rows * 2 columns. Each cell contains 3 bits, the 2 MSBs indicate the next state and the LSB is the next output.

I have tried this implementation both with blocking and non-blocking assignments, but it still doesn't work.

I'm using EPWave and EDAPlayground with Icarus Verilog as simulator. What I'm getting is that o (the output) is undetermined most of the time, and r (which is a debug wire used to see the internal current state goes like 0, 1, 2, X and remains in X for the rest of the simulation)

What am I missing?

PD.: simulation

Here is a link that should allow you to simulate the code: edaplayground. Notice there are two modules: the first one is the case/if one, which already works. The module I'm trying to debug is ex10_1_2.


Solution

  • I have replaced the matrix declaration by the followin:

    reg [2:0] ttable [3:0][1:0];
    

    it seems that I had an out-fo-bounds error because of the previous [1:0]. I was confused because I though I would have enough with 2 bits, since that is what the state codes need. However this is an array index, therefore I need 4 positions, one for each state.