我对Verilog有些陌生。我知道在时钟进程中我们应该使用非阻塞赋值,而在非时钟进程中,我们使用阻塞赋值。
当我读别人的代码时,我遇到过这段代码。
reg iowrb_int,iowrb_met;
reg iordb_int,iordb_met;
always@(*)
begin
iowrb_int <= iowrb_met;
iordb_int <= iordb_met;
iowrb_met <= iowr_bar;
iordb_met <= iord_bar;
end我对上面的代码真的不太确定!我不认为它在做任何注册,对吗?在always@(*)语句中使用非阻塞是否意味着什么?
在always@(*)语句中使用阻塞和非阻塞有什么区别吗?
发布于 2014-03-22 01:45:05
主要区别是:
假设a=2,b=3,则非阻塞赋值:
a <= 4;
b <= a; 结果a=4和b=2-赋值前的a的值
但
a = 4;
b = a;在阻塞分配完成后,将导致a=4和b=4 -值为a。
与组合逻辑相比,将变量合成到寄存器(锁存器或触发器)取决于always块的敏感度列表。它不依赖于阻塞或非阻塞赋值的使用。
例如:
always @(*) begin
if (enable)
q = d;
end这将导致D锁存,因为没有为enable==0指定对Q的赋值,因此它需要记住是最后一个赋值。
而
always @(*) begin
if (enable)
q = d;
else
q = f;
end这将导致多路复用(组合逻辑),因为对于启用的两种情况都指定了对Q的赋值,因此Q不需要记住任何东西。
发布于 2014-03-22 01:54:44
阻塞与非阻塞是为了使你的门级(合成)与你的RTL模拟匹配。据我所知,使用不同的一个来改变模拟的行为不会影响合成,因此也不会影响门级的行为。
<=非阻塞有效地获取副本右侧的临时副本,并在时间步长结束时进行=阻塞分配。
a <= b;
b <= a;等同于:
a_temp = b;
b_temp = a;
//
a = a_temp;
b = b_temp;该示例使用组合逻辑,即它不包含状态,因此所有输入必须由所有输出定义。
always@* begin
iowrb_int <= iowrb_met;
iordb_int <= iordb_met;
iowrb_met <= iowr_bar;
iordb_met <= iord_bar;
end当右侧更新时,应重新触发该块。由于iowrb_met是两边的,我不确定这意味着什么电连接。
虽然<=意味着复制到临时位置,但组合逻辑没有这种功能,它总是由赋值连续驱动。
我认为在模拟中,你实际上有这样的东西:
always@* begin
iowrb_int_temp = iowrb_met;
iordb_int_temp = iordb_met;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
iowrb_int = iowrb_int_temp;
iordb_int = iordb_int_temp;
end在硬件中,您将拥有:
always@* begin
iowrb_int = iowrb_met; //= iowr_bar;
iordb_int = iordb_met; //= iord_bar;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
end其中iowrb_int实际上与iowrb_met相同
触发器使用always @(posedge clk隐含
组合逻辑使用always @*隐含,但当输出不是从输入完全定义时,可以隐含锁存器。
发布于 2014-03-22 02:48:11
通过仅将代码更改为阻塞赋值,它可以根据工具句柄来合成锁存器和/或创建逻辑等价检查不匹配。
下面是它在调度器中的外观:
具有阻塞功能的
1. The `*_int` signals are assigned
2. The `*_met` signals are assigned
3. Move on to the next time step.
- `*_int` keeps the non-updated values of `*_met`
具有非阻塞功能的
1. The `*_int` signals are assigned
2. The `*_met` signals are assigned
3. A change to `*_met` is detected causes a loop back the the _Active_ region of the scheduler
4. Re-assign the `*_int` signals
5. Re-assign the `*_int` signals
6. Move on to the next time step.
- `*_int` has the same values as `*_met`
- Waste CPU time to reprocessing. This is not important on a small project, but can add noticeable overhead used throughout a large project.
正确的、逻辑上等效的、对CPU友好的方法是颠倒分配顺序(在*_int之前分配*_met ):
always@(*)
begin
iowrb_met = iowr_bar;
iordb_met = iord_bar;
iowrb_int = iowrb_met;
iordb_int = iordb_met;
endassigned
*_int *_met信号被分配到下一个时间步长。*_int与*_met具有相同的值
或使用*_bar作为赋值(即,如果是a==b和b==c,则是a==b和a==c):
always@(*)
begin
iowrb_int = iowr_bar;
iordb_int = iord_bar;
iowrb_met = iowr_bar;
iordb_met = iord_bar;
end将assigned
*_int和*_met信号切换到下一个时间步长。*_int与*_met具有相同的值
https://stackoverflow.com/questions/22565475
复制相似问题