例如,假设我有reg [7:0] myReg
我为它赋值-8'D69
我知道Verilog将它存储为2的补码,因此它应该存储为
10111011
我现在的问题是,如果我要对它进行操作,比如myReg / 2
它会评估为-34吗?或者它需要10111011并将其转换为187然后执行除法,返回93?
答案 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'sd69
或69
。
我现在的问题是,如果我要对它进行操作, 说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