例如,說我有一個reg [7:0] myReg
我賦予它的價值-8'D69
Verilog如何以負數表現?
我知道的Verilog把它存儲爲2的補,所以應該被存儲爲
10111011
我現在的問題是,如果我將執行一個操作,說myReg/2
它會評估爲-34?或者是否需要10111011並將其轉化爲187,然後執行該部門,返回93?
例如,說我有一個reg [7:0] myReg
我賦予它的價值-8'D69
Verilog如何以負數表現?
我知道的Verilog把它存儲爲2的補,所以應該被存儲爲
10111011
我現在的問題是,如果我將執行一個操作,說myReg/2
它會評估爲-34?或者是否需要10111011並將其轉化爲187,然後執行該部門,返回93?
您需要記住-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
也在我的示例中四捨五入,>>>
將捨去/截斷。
例如,說我有一個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
我會補充說 1.數據類型位和reg是無符號,默認情況下。 2.默認情況下,數據類型int,integer,longint,shortint和byte是有符號的。 3.所有這些數據類型都可以使用帶符號或無符號限定符來更改默認值。
因此,將-8'D69分配給myReg將隱式轉換爲187.然後,myReg/2 = 187/2 = 93,無符號。瞭解SystemVerilog何時以及如何在表達式和賦值中進行隱式類型轉換非常重要。
你也應該這樣聲明有符號的數字。 'reg signed [7:0] my_reg' – Morgan
您可以使用>>> 1執行符號擴展除以2(如果它被聲明爲帶符號類型)。 – Morgan