使用二维数组作为转换 table 在 Verilog 中实现状态机
Implement a state machine in Verilog using a 2D array as transition table
我正在尝试在 Verilog 中实现一个非常简单的 Mealy 状态机。我已经用 case
和 if
语句完成了它,但是为了清楚起见,我希望能够使用二维数组作为转换 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 个位置,每个状态一个。
我正在尝试在 Verilog 中实现一个非常简单的 Mealy 状态机。我已经用 case
和 if
语句完成了它,但是为了清楚起见,我希望能够使用二维数组作为转换 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 个位置,每个状态一个。