问题描述
我有 SystemVerilog 代码,其中使用了我不理解的复制。请认真回答。
parameter WIDTH = 6;
logic [WIDTH-1:0] flag,flag2;
`define ZERO_X(n,m) {{m-$bits(n){1'b0}},(n)}
assign flag = flag2 - `ZERO_X(1'b1,WIDTH);
解决方法
第一步是在这个表达式中执行简单的文本替换。将 n
替换为 1'b1
,将 m
替换为 WIDTH
。所以这个:
`ZERO_X(1'b1,WIDTH)
变成:
{{WIDTH-$bits(1'b1){1'b0}},(1'b1)}
用 WIDTH
替换 6
:
{{6-$bits(1'b1){1'b0}},1'b1}
$bits(1'b1)
的计算结果为 1
:
{{(6-1){1'b0}},1'b1}
6-1
就是 5
:
{{5{1'b0}},1'b1}
{5{1'b0}}
将 1'b0
复制到 5 个 0:
{5'b0_0000,1'b1}
然后简单的连接:
6'b00_0001
因此,这一行:
assign flag = flag2 - `ZERO_X(1'b1,WIDTH);
评估为:
assign flag = flag2 - 6'b00_0001;
,
此代码试图将其操作数 0 扩展到 WIDTH,完全没有必要。根据 Verilog 规则,1'b1
操作数已经扩展到它所写入的表达式上下文中最大操作数的宽度。
assign flag = flag2 - 1'b1;
但是如果您想清楚地显示该扩展名,您可以编写一个明确的演员表:
assign flag = flag2 - WIDTH'(1'b1);