【问题标题】:wire in always block/case statement - Verilog在总是块/案例语句中连线 - Verilog
【发布时间】:2015-11-07 05:31:37
【问题描述】:

以下是使用 case 语句并始终使用 @(*) 块的示例代码。我不明白 always 块是如何被触发的,以及为什么即使 x 被声明为线,它也能工作。

wire [2:0] x = 0;
always @(*)
begin
case (1'b1)
  x[0]: $display("Bit 0 : %0d",x[0]);
  x[1]: $display("Bit 1 : %0d",x[1]);
  x[2]: $display("Bit 2 : %0d",x[2]);
  default: $display("In default case");
endcase
end

感谢任何帮助。

谢谢。

【问题讨论】:

    标签: case verilog system-verilog


    【解决方案1】:

    众所周知,reg 可以由wire 驱动,我们绝对可以在任何程序块中使用wire 作为赋值的右侧。

    在这里,您的代码检查x 的哪一位是1'b1(当然将优先级 赋予第零位)。假设x 更改为3'b010。然后,应显示Bit 1 等等。现在,如果x=3'b011 则显示Bit 0,因为首先检查第零位。

    如您所见,x 没有赋值,程序块仅读取其值。而且系统任务$display也读取了x的值。

    此块的信号值没有变化。因此,此代码工作正常。如果碰巧我们有类似x[0] = ~x[0] 而不是$display,那么这段代码将提供编译问题。

    更多信息请访问thisthis 链接。

    【讨论】:

    • 谢谢。我们可以使用 $fwrite 或从这个始终阻塞的线路上立即断言吗?
    • 是的。立即断言可以写在这里。但这取决于您如何使用它们。如果通过任何方式,x 的值发生变化,则将导致错误。我不确定 $fwrite,但我想它也应该可以工作。
    【解决方案2】:

    这里,always 块不会给 x 赋值,而只是检查 x 的值。所以这是对电线的合法使用。

    【讨论】:

    • 谢谢。我们可以使用 $fwrite 或从这个始终阻塞的线路上立即断言吗?
    【解决方案3】:

    因此,您对always @(*) 是如何触发的部分问题的解释如下:

    “出现在赋值右侧、子程序调用中、case 和条件表达式中的网络和变量,作为赋值左侧的索引变量,或作为 case 项中的变量表达式都应始终包含在 @(*) 中。”

    参考:IEEE Std 1800-2012 Sec 9.4.2.2

    作为@sharvil111 答案的扩展,如果您的代码是这样的

    always @(*)
    begin
    
    case (sel)
    x[0]: $display("Bit 0 : %0d",x[0]);
    x[1]: $display("Bit 1 : %0d",x[1]);
    x[2]: $display("Bit 2 : %0d",x[2]);
    default: $display("In default case");
    
    endcase
    end
    

    只要 sel 信号或 x 发生变化,就会触发程序块,即它相当于 always @(sel or x)。

    【讨论】:

    • 所以,在我目前的情况下,我认为它必须等同于 always @(x),对吗?谢谢您的答复。我们可以使用 $fwrite 或从这个总是块的线路上立即断言吗?例如assert (x[0] == 1'b0)$fwrite(file,"x is%0d",x)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多