代码如下:
module my_module(
input wire clk,
input wire rst,
input wire ina,
input wire inb,
...
);
reg[1:0] queue;
reg[3:0] cur_state, next_state;
reg[1:0] value;
always @(posedge clk) begin
if (rst) begin
next_state <= 4'b0000;
end else begin
next_state <= cur_state;
end
end
always @(*) begin
if (rst) begin
queue = 2'b00;
end else begin
if (ina) begin
queue[0] = 1'b1;
end
if (inb) begin
queue[1] = 2'b1;
end
case (cur_state)
4'b0000: begin
if (queue[0]) begin
value = 2'b01;
next_state = 4'b0001;
end else if (queue[1]) begin
value = 2'b10;
next_state = 4'b0001;
end
end
4'b0001: begin
if (value...)
...
end
end
end
endmodule
这段代码的逻辑类似于总线接口,它分别接受来自inst/data cache的访问请求(可能同时),inst访问优先于data,所以在0000状态里用if/else,之后就是同步的逻辑,直到下一次进入0000状态并且queue有访问继续。
用modelsim仿真完全没有问题,但是用verilator去仿真会得到"active region value did not converge"的错误,就是说value的值在快速变化。我后来理解了,是因为在0000状态,queue的值是随时会变化的,因为是组合电路导致value的值也在随时变化(虽然ina/inb都只一个持续一个时钟周期)。
把FSM第二段改成时序逻辑应该是能解决这个问题,因为这样queue值只在时钟上升沿发生变化,但执行时间会化更多时钟周期。
哪位大神好招吗?
--
FROM 125.33.202.*