Verilog 为什么有负值的有符号文字?

Verilog 为什么有负值的有符号文字?,verilog,system-verilog,Verilog,System Verilog,这是一个简单的问题,但我以前从未真正看到过答案。在Verilog(或SystemVerilog)中,可以声明一个文本并指示使用的位数。例如: reg [3:0] x = 4'b1101; // (1) reg [3:0] y = 4'd13; // (2) 这里声明了寄存器x和y,它们最初持有相同的值。也可以使用带符号的修饰符。使用它的一些例子有: reg signed [3:0] a = 4'sb0101; // (3) reg signed [3:0] b = 4'sd5; //

这是一个简单的问题,但我以前从未真正看到过答案。在Verilog(或SystemVerilog)中,可以声明一个文本并指示使用的位数。例如:

reg [3:0] x = 4'b1101; // (1)
reg [3:0] y = 4'd13;   // (2)
这里声明了寄存器x和y,它们最初持有相同的值。也可以使用带符号的修饰符。使用它的一些例子有:

reg signed [3:0] a = 4'sb0101; // (3)
reg signed [3:0] b = 4'sd5;    // (4)
现在,我的问题是如何用十进制表示法表示负值。假设我们要将寄存器c和d初始化为-3。这是正确的吗

reg signed [3:0] c = 4'sb1101; // (5)
reg signed [3:0] d = -4'sd3;   // (6)
以上代码在我当前版本的ActiveHDL中编译和运行。对我来说,它似乎在语义上暗示了以下几点:对0011的表示进行否定(位倒置,加一)以获得1101(我想要表示的实际文字)。注意,我们在这里使用了否定运算符。我经常想知道是否有另一种直接表示数字的方法。我尝试了
4'sd(-3)
,这对我来说似乎更干净,因为现在宽度和表示的值是解耦的。但是,这给了我语法错误。我已经在初始化中做了标记为(6)的工作,但这仍然回避了一个问题

如果指定宽度的文字不能包含负值(没有运算符对其进行操作),为什么要为指定宽度的文字设置有符号修饰符

换句话说,文字
-4'sd3
如何优于(或不同于)文字
-4'd3

替代解决方案:演示如何以更好的方式表示负值有符号文字。

您可以使用
4'(-3)
这是将表达式强制转换为指定宽度4

如LRM所述,
s
修饰符不影响所表示的位模式;只是它的解释。如果你有

module top;

  reg signed  [5:0] a;
  initial begin
    a = -4;
    $display(a<4'b1101);
    $display(a<4'sb1101);
  end
endmodule
模块顶部;
注册签名[5:0]a;
初始开始
a=-4;

$display(a两个
-4'sd3
-4d3
是相同的

如果包含s指示符,则使用基本格式指定的数字应视为有符号整数;如果仅使用基本格式,则应视为无符号整数

s指示符不影响指定的位模式,只影响其 解释。大小常数前的加号或减号运算符 是一元加减运算符。介于 基本格式和数字是非法语法


这是一个有趣的替代方案。我在串联有符号值时使用了很多次。我在写问题时没有想到。负号是否意味着最终值将在表达式中被视为有符号?因此类似于a=b*4'(-1)的内容将导致有符号乘法(假设b有符号)?我想我可以自己试试。是的,LRM说签名没有改变。Karan,我想你的意思是说-4'sd3和-4'd3是一样的?(你错过了字符)。不过谢谢你的回复。
    8'd-6   // this is illegal syntax
    -4'sd15 // -15, equivalent to -4'd15, or '0001'
    16'sd?  // the same as 16'sbz