防止 Verilog case 语句中出现锁存
我无法理解如何防止在 Verilog 项目中创建锁存器。我知道正在创建锁存器,因为我没有指定每个 case 语句中所有信号发生的情况。但是,我不知道是否有任何方法可以避免这种情况(除了我目前使用的严厉方法之外)。
我目前有两个移位寄存器,register X
和 register R
。每个移位寄存器都有一个 5 位宽的控制总线,由有限状态机控制。为了使这些移位寄存器的管理更容易,我希望利用按位操作来设置和取消设置控制总线位。
例如,在状态done
下,我需要取消设置register R
的shiftRight
位。为了做到这一点,我可以执行以下按位运算:
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
这非常有效。下面,您可以看到我为寄存器控制总线定义的所有信号和按位运算。然而,由于我不需要修改每个状态中两个寄存器的所有寄存器控制总线,所以我最终得到了锁存器。例如,在下面的状态done
中,我只需要修改寄存器R
的寄存器控制总线。结果,为寄存器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
I'm having trouble understanding how I can prevent latches from being created within a Verilog project. I understand that latches are being created because I am not specifying what occurs to all signals within each case statement. However, I do not know if there is any way to avoid this (other then the draconian method which I have used at the moment).
I currently have two shifter registers, register X
and register R
. Each of these shifter registers has a 5-bit wide control bus, controlled from a finite state machine. In order to make management of these shifter registers easier, I was hoping to utilize bitwise operations to set and unset control bus bits.
For instance, in state done
, I need to unset the shiftRight
bit for register R
. In order to do this, I can perform the following bitwise operation:
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
This works perfectly. Below, you can see all of the signals and bitwise operations which I have defined for the register control bus. However, since I do not need to modify all of the register control buses for both registers within each state, I end up with latches. For instance, within state done
below, I only need to modify the register control bus for register R
. As a result, a latch is created for register X
control bus.
At the moment, I've resolved this by simply setting all of the bits for both of the register control buses within each state of the state machine, throwing away my idea to perform bitwise operations on the signals.
However, I believe the bitwise operation method is cleaner -- I would like to know if there is anyway for me to continue to use this method without dealing with latches. It makes the code much easier to read and modify.
As always, thanks for any assistance.
// 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;
Previous solution:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是 verilog - 您可以直接获取这些位。也许将参数更改为位索引:
This is verilog - you can get at the bits directly. Maybe change your parameters to bit indices:
To avoid latches, and to avoid having to write loads of verilog to make sure each logic branch sets all variables, I'm using a technique for which I don't know the name of!
The idea is to set any variables you're assigning to within an
always
procedure to some set of reasonable 'defaults' at the beginning. Then you can treat any deviations from these defaults as special cases and not have to worry about making sure all your variables are set in all branches of your code - they will get the 'default' value.这种类型的行不适合组合语句。
输入组合地影响该行中的输出。该工具会看到这一点并让您知道这是一个问题。为了使问题更清楚并显示该工具所担心的是什么,想象一下如果我写道:
组合地,信号总是想要反转,并且它将以逻辑传播的速度这样做。我刚刚制作了一个振荡器,因为它永远不会进入静止状态。这些工具知道这可能不是我想要的,并让我知道。
This type of line is not good for a combinatorial statement.
The input effects the output in this line combinatorially. The tool sees this and lets you know it's a problem. To make the problem more clear and to show what it is that the tool is worried about, imagine if I wrote:
Combinatorially, the signal always wants to invert and it will do so at the speed of the logic propagation. I have just made an oscillator because it will never come to a resting state. The tools knows this probably isn't what is desired and lets me know.