【问题标题】:Systemverilog expansion ruleSystemverilog 扩展规则
【发布时间】:2021-10-28 00:43:11
【问题描述】:

当我查看一些代码时,我发现了一些奇怪的东西。
看来是来自扩展和操作优先级。
(我知道因为“sig”是用 'signed' 声明的,所以 $signed 不是必需的,而且 '-sig' 是正确的,无论如何..)

reg signed [9:0] sig;
reg signed [11:0] out;

initial
begin
    $monitor ("%0t] sig=%0d, out=%0h", $time, sig, out);
    sig = 64;
    out = $signed(-sig);
#1
    out = -$signed(sig);
#1
    sig = -512;
    out = $signed(-sig);
#1
    out = -$signed(sig);
#1
$finish;
end

以上代码的模拟结果是,

0] sig=64, out=-64
2] sig=-512, out=-512
3] sig=-512, out=512

当sig=-512时,我预计10位sig在取反前会扩展为12位,但在取反后却被扩展了。
所以-512的否定还是-512,展开后是-512。
我猜“$signed() 阻止扩展..知道会发生什么吗??

【问题讨论】:

    标签: system-verilog expansion


    【解决方案1】:

    首先,-512512 在 10 位表示中是相同的数字。 10 位实际上只能保存从 -512 到 511 的有符号值。在这个方案中,-512 的否定应该很奇怪,在 lrm 中没有提到,至少我无法找到任何相关的东西。这可能是一种未定义的行为。

    然而,假设在这个方案中为了表示“-512”的否定值,只需删除符号就足够了。似乎 eda playground 中的所有商业编译器都这样做。因此,在这种情况下,unaray - 运算符的结果将是 unsigned 值 512。

    因此,在out = $signed(-(-512)) 中,否定运算符返回一个无符号值 512,并由系统任务转换为有符号值。因此,它会被扩展签入。

    out = -$signed(-512) 出于同样的原因,最外面的否定运算符返回一个无符号值 512。这里没有发生符号扩展。

    您可以通过将另一个 $signed 封装为 out = $signed(-$signed(-512)) 来再次对其进行签名

    【讨论】:

    • 嗯.. '-' 算术运算符是一元运算符,但不是归约运算符,我的理解是只有归约运算符返回无符号值。类似的例子是 A = 3'b100 ; B = 3'b100;出 = $ 签名(A + B); // 逻辑符号 [7:0] out;那么 out 是 '0' 并且似乎 $signed 内部形成了一个表达式并在评估后扩展。
    • 归约运算符返回 1 位值
    • 是的,在表达式中使用时其属性是无符号的。 systemverilog LRM 说“比较和归约运算符的结果是无符号的,无论操作数如何。”无论如何..
    猜你喜欢
    • 1970-01-01
    • 2017-07-08
    • 2020-10-20
    • 2012-12-24
    • 2021-01-31
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多