首页 > 解决方案 > Verilog改变右手边的大小

问题描述

我有一个如下的基本模块来演示一些东西。

module tb();

reg [2:0] U;
reg [2:0] T;
reg [2:0] C;
reg E;

initial begin

    U = 5;
    T = 3;
    {E, C} = U + ~T + 1'b1;
    #1000;

end

endmodule

我期望 E 为 1,因为;

U101

T011

并且U + ~T + 001是,

   101
   100
   001
+______
= 1010 

因此,C 得到 010 部分,E 得到 1。这是预期的行为,但是,我得到 C 相同但 E 为 0。我认为 verilog 将 RHS 变量的大小增加到 4 位,因为左侧是 4 位( 1+3)。但是,对于 T,它在补码 T 之前附加了前导 0,因此 T 变为 0011,其补码恰好是 1100,而不是 0100,即 T 补码的 4 位版本。

这导致,

   0101
   1100
   0001
+______
= 10010 

如所见,这导致 E 为 0。

我不明白为什么会这样,并且在添加前导零之前找不到一种方法来进行补充。

如果我改为执行以下操作,它可以正常工作并且 E 得到 1:

    U = 5;
    T = 3;
    T = ~T;
    {E, C} = U + T + 1'b1;

这证实了我的猜想是对的。所以,我确实有这样的解决方案,是的。但是,我对此并不满意,我认为应该有一种方法可以防止这种行为。

任何帮助,将不胜感激。

标签: verilog

解决方案


当您有混合不同宽度的操作数时,Verilog 有规则根据表达式的上下文将每个操作数的大小调整为最大操作数的宽度。您正确地注意到 LHS 是 4 位,RHS 上的操作数被扩展为 4 位。这发生应用操作之前。

您可以利用串联的操作数是自行确定的上下文这一事实来解决此问题:

{E, C} = U + {~T} + 1'b1;

现在 的宽度~T完全由 的宽度决定T


推荐阅读