使用二维数组作为转换 table 在 Verilog 中实现状态机

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

我正在尝试在 Verilog 中实现一个非常简单的 Mealy 状态机。我已经用 caseif 语句完成了它,但是为了清楚起见,我希望能够使用二维数组作为转换 table 来做同样的事情。

代码如下:

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

如您所见,过渡 table 是 4 行 * 2 列。每个单元包含 3 位,2 个 MSB 表示下一个状态,LSB 是下一个输出。

我已经用阻塞和非阻塞分配尝试过这个实现,但它仍然不起作用。

我使用 EPWave 和 EDAPlayground 以及 Icarus Verilog 作为模拟器。我得到的是 o(输出)大部分时间是不确定的,r(这是用于查看内部当前状态的调试线,如 0、1、2, X 并在模拟的其余部分保持在 X 中)

我错过了什么?

PD.:模拟

这里有一个 link 应该可以让您模拟代码:edaplayground。注意有两个模块:第一个是 case/if 模块,它已经可以工作了。我要调试的模块是 ex10_1_2.

我已将矩阵声明替换为以下内容:

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

我好像因为之前的[1:0]出现了越界错误。我很困惑,因为我认为 2 位就足够了,因为那是州代码所需要的。然而这是一个数组索引,因此我需要 4 个位置,每个状态一个。