14

例如,假设我有一个reg [7:0] myReg 我给它赋值-8'D69

我知道 Verilog 将其存储为 2 的补码,因此应将其存储为

10111011

我现在的问题是,如果我要对其执行操作,比如 myReg/2

它会评估为-34吗?还是将 10111011 转换为 187 然后执行除法,返回 93?

4

3 回答 3

15

你需要记住这-8d69只是一个模式。reg 是一种保存位模式的类型。它是指示/执行有符号或无符号算术的变量类型。

如果这是为了综合考虑你想尽量避免使用分隔符,你真的想尝试避免有符号的分隔符。它可能会合成更小>>> 1

reg [7:0] a;
reg signed [7:0] b;
reg [7:0] c;
reg signed [7:0] d;

initial begin
  a =  -8'd69 ;
  b =  -8'd69 ;
  c =  -8'd69 ;
  d =  -8'd69 ;
  #10ns;
  a = a/2     ;
  b = b/2     ;
  #10ns;
  $display("a      : %8b, %d", a, a);
  $display("b      : %8b, %d", b, b);
  $display("c >>>1 : %8b, %d", c>>>1, c>>>1);
  $display("d >>>1 : %8b, %d", d>>>1, d>>>1);
end

给出:

a      : 01011101,  93
b      : 11011110,  -34 
c >>>1 : 01011101,  93
d >>>1 : 11011101,  -35

>> x右移 x 位,>>> x右移 x 位,但符号扩展为有符号类型。

注意:/2在我的示例中也是四舍五入,>>>将向下舍入/截断。

于 2012-09-13T09:45:48.747 回答
6

例如,假设我有一个 reg [7:0] myReg 我给它赋值 -8'D69

这实际上不是一个有符号数,而是一个由应用于正常数的一元否定组成的表达式。如果表达式是-8'd130结果将溢出。有符号常量被声明为8'sd6969

我现在的问题是,如果我要对其执行操作,比如 myReg/2

myReg是无符号的,因此表达式结果也将是无符号的*。如果您需要对结果进行签名,则必须对所有操作数进行签名。有几种方法可以实现这一点:

//Declare the reg as signed and divide by a signed value
reg signed [7:0] myReg;
assign result = myReg/2;

//Use system functions
assign result = $signed(myReg)/2;

*关于表达式求值的完整规则要复杂得多,但基本上任何表达式的结果都是无符号的,除非所有操作数都有符号。

reg signed [7:0] a;
reg [7:0] b;

initial
begin
result = a;            //Signed
result = a * a;        //Signed
result = a * 10;       //Signed
result = $unsigned(a); //Unsigned
result = a[0];         //Unsigned
result = a[7:0];       //Unsigned
result = {a,a};        //Unsigned
result = 10{a};        //Unsigned
result = a + b;        //Unsigned
result = a * b;        //Unsigned
end
于 2012-09-13T16:07:47.613 回答
1

我将添加 1。默认情况下,数据类型 bit 和 reg 是无符号的。2. 默认情况下,数据类型 int、integer、longint、shortint 和 byte 是有符号的。3. 所有这些数据类型都可以使用有符号或无符号限定符来更改默认值。

因此,将 -8'D69 分配给 myReg 会隐式转换为 187。然后,myReg/2 = 187/2 = 93,无符号。了解 SystemVerilog 何时以及如何在表达式和赋值中进行隐式类型转换非常重要。

于 2012-10-10T22:24:40.347 回答