我无法理解如何防止在 Verilog 项目中创建闩锁。我知道正在创建锁存器,因为我没有指定每个 case 语句中的所有信号会发生什么。但是,我不知道是否有任何方法可以避免这种情况(除了我目前使用的严厉方法)。
我目前有两个移位寄存器,register X
和register R
. 这些移位寄存器中的每一个都有一个 5 位宽的控制总线,由有限状态机控制。为了使这些移位寄存器的管理更容易,我希望利用按位运算来设置和取消设置控制总线位。
例如,在 state 中done
,我需要取消shiftRight
设置register R
. 为此,我可以执行以下按位运算:
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
这完美地工作。下面,您可以看到我为寄存器控制总线定义的所有信号和按位操作。但是,由于我不需要修改每个状态中两个寄存器的所有寄存器控制总线,所以我最终得到了锁存器。例如,在下面的状态done
中,我只需要修改寄存器控制总线register R
。结果,为register X
控制总线创建了一个锁存器。
目前,我通过简单地在状态机的每个状态中设置两个寄存器控制总线的所有位来解决这个问题,放弃了对信号执行按位运算的想法。
但是,我相信按位操作方法更干净——我想知道是否有任何方法让我继续使用这种方法而不处理闩锁。它使代码更容易阅读和修改。
一如既往,感谢您的帮助。
// Register Control Bus Signals
// bit # - purpose
// 0 - reset (rst)
// 1 - load (ld)
// 2 - shift left (sl)
// 3 - shift right (sr)
// 4 - auxilary 1 (mux select)
parameter register_ctrl_reset = 5'b00001;
parameter register_ctrl_load = 5'b00010;
parameter register_ctrl_shiftLeft = 5'b00100;
parameter register_ctrl_shiftRight = 5'b01000;
parameter register_ctrl_auxilary = 5'b10000;
parameter register_ctrl_width = 5;
output reg [register_ctrl_width-1:0] xRegisterControlBus;
output reg [register_ctrl_width-1:0] rRegisterControlBus;
以前的解决方案:
always@(currentState, ryCompareOut)
begin
case(currentState)
shiftRight:
begin
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftLeft;
xRegisterControlBus = xRegisterControlBus & ~register_ctrl_shiftLeft;
rRegisterControlBus = rRegisterControlBus | register_ctrl_shiftRight;
end
done:
begin
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
end
endcase
end