Verilog如何处理负数?

时间:2012-09-13 05:33:40

标签: verilog negative-number

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

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

10111011

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

它会评估为-34吗?或者它需要10111011并将其转换为187然后执行除法,返回93?

2 个答案:

答案 0 :(得分:14)

你需要记住-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也在四舍五入,>>>将向下舍入/截断。

答案 1 :(得分: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