2012-09-13 1226 views
9

例如,說我有一個reg [7:0] myReg 我賦予它的價值-8'D69Verilog如何以負數表現?

我知道的Verilog把它存儲爲2的補,所以應該被存儲爲

10111011 

我現在的問題是,如果我將執行一個操作,說myReg/2

它會評估爲-34?或者是否需要10111011並將其轉化爲187,然後執行該部門,返回93?

+1

你也應該這樣聲明有符號的數字。 'reg signed [7:0] my_reg' – Morgan

+0

您可以使用>>> 1執行符號擴展除以2(如果它被聲明爲帶符號類型)。 – Morgan

回答

10

您需要記住-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也在我的示例中四捨五入,>>>將捨去/截斷。

5

例如,說我有一個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

我會補充說 1.數據類型位和reg是無符號,默認情況下。 2.默認情況下,數據類型int,integer,longint,shortint和byte是有符號的。 3.所有這些數據類型都可以使用帶符號或無符號限定符來更改默認值。

因此,將-8'D69分配給myReg將隱式轉換爲187.然後,myReg/2 = 187/2 = 93,無符號。瞭解SystemVerilog何時以及如何在表達式和賦值中進行隱式類型轉換非常重要。