首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Verilog阻塞分配

Verilog阻塞分配
EN

Stack Overflow用户
提问于 2014-03-22 01:24:32
回答 4查看 4.2K关注 0票数 3

我对Verilog有些陌生。我知道在时钟进程中我们应该使用非阻塞赋值,而在非时钟进程中,我们使用阻塞赋值。

当我读别人的代码时,我遇到过这段代码。

代码语言:javascript
复制
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@(*)语句中使用阻塞和非阻塞有什么区别吗?

EN

回答 4

Stack Overflow用户

发布于 2014-03-22 01:45:05

主要区别是:

  • 阻塞赋值在下一个赋值之前执行,即它会阻塞下一个并行执行的statement.
  • non-blocking赋值,即它们不会阻塞它们后面的语句的执行。

假设a=2,b=3,则非阻塞赋值:

代码语言:javascript
复制
a <= 4;
b <= a; 

结果a=4和b=2-赋值前的a的值

代码语言:javascript
复制
a = 4;
b = a;

在阻塞分配完成后,将导致a=4和b=4 -值为a。

与组合逻辑相比,将变量合成到寄存器(锁存器或触发器)取决于always块的敏感度列表。它不依赖于阻塞或非阻塞赋值的使用。

例如:

代码语言:javascript
复制
always @(*) begin
  if (enable)
     q = d;
end

这将导致D锁存,因为没有为enable==0指定对Q的赋值,因此它需要记住是最后一个赋值。

代码语言:javascript
复制
always @(*) begin
  if (enable)
    q = d;
  else
    q = f;
end

这将导致多路复用(组合逻辑),因为对于启用的两种情况都指定了对Q的赋值,因此Q不需要记住任何东西。

票数 3
EN

Stack Overflow用户

发布于 2014-03-22 01:54:44

阻塞与非阻塞是为了使你的门级(合成)与你的RTL模拟匹配。据我所知,使用不同的一个来改变模拟的行为不会影响合成,因此也不会影响门级的行为。

<=非阻塞有效地获取副本右侧的临时副本,并在时间步长结束时进行=阻塞分配。

代码语言:javascript
复制
a <= b;
b <= a;

等同于:

代码语言:javascript
复制
a_temp = b;
b_temp = a;
//
a = a_temp;
b = b_temp;

该示例使用组合逻辑,即它不包含状态,因此所有输入必须由所有输出定义。

代码语言:javascript
复制
always@* begin
  iowrb_int <= iowrb_met;
  iordb_int <= iordb_met;
  iowrb_met <= iowr_bar;
  iordb_met <= iord_bar;
end

当右侧更新时,应重新触发该块。由于iowrb_met是两边的,我不确定这意味着什么电连接。

虽然<=意味着复制到临时位置,但组合逻辑没有这种功能,它总是由赋值连续驱动。

我认为在模拟中,你实际上有这样的东西:

代码语言:javascript
复制
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

在硬件中,您将拥有:

代码语言:javascript
复制
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 @*隐含,但当输出不是从输入完全定义时,可以隐含锁存器。

票数 1
EN

Stack Overflow用户

发布于 2014-03-22 02:48:11

通过仅将代码更改为阻塞赋值,它可以根据工具句柄来合成锁存器和/或创建逻辑等价检查不匹配。

下面是它在调度器中的外观:

具有阻塞功能的

代码语言:javascript
复制
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`

具有非阻塞功能的

代码语言:javascript
复制
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 ):

代码语言:javascript
复制
always@(*)
begin
  iowrb_met = iowr_bar;
  iordb_met = iord_bar;

  iowrb_int = iowrb_met;
  iordb_int = iordb_met;
end

assigned

  • Move on to
  1. *_int
  2. *_met信号被分配到下一个时间步长。
    • *_int*_met

具有相同的值

使用*_bar作为赋值(即,如果是a==b和b==c,则是a==b和a==c):

代码语言:javascript
复制
always@(*)
begin
  iowrb_int = iowr_bar;
  iordb_int = iord_bar;

  iowrb_met = iowr_bar;
  iordb_met = iord_bar;
end

将assigned

  • Move

  • *_int*_met信号切换到下一个时间步长。
  • *_int*_met

具有相同的值

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22565475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档