2017-07-19 260 views

回答

0

一個例子可能是照亮的。

module top; 

reg [3:0] a; 
reg [3:0] b; 

reg [7:0] r1; 
reg [7:0] r2; 

initial begin 
    a = 4'hc; 
    b = 4'h5; 
    r1 = a * b; // 12 * 5 
    r2 = $signed(a) * $signed(b); //-4 * 5 
    $display("r1 = %b", r1); 
    $display("r2 = %b", r2); 
end 


endmodule 

結果:

r1 = 00111100 (60) 
r2 = 11101100 (-20) 

所不同的是帶符號的數字利用向量作爲符號的指示符的MSB(見here,沒有真正閱讀此),該轉移可表達的號碼範圍從[0..2^n-1][-2^(n-1)..2^(n-1)-1]

幾件事情需要注意:

  1. Verilog很奇怪,只會產生一個簽名結果,如果 操作數被簽名。
  2. 您可以將一個reg/wire標記爲reg signed [3:0] foo$signed系統任務。如果你有子表達式,你想把它視爲有符號的,後者通常很有用。例如,即使原始變量被簽名,取一個向量片也總是無符號的。
  3. 我提供的鏈接還涵蓋了乘以有符號數量時獲得正確答案所需機制的輕微變化。

對於Verilog的行爲劃分的目的基本上是相同的,雖然除非處理嚴格的2的權力通常是不可合成的。

0

只是有點不同基於Brian的例子

的Verilog簽名VS無符號算術視圖導致符號傳播和關係操作的差異。如果不涉及符號擴展,對2進制數據的正則運算產生相同的有符號和無符號結果

所以在這種情況下,如果r1和r2的大小爲'4'(作爲操作數)相同的結果:

r1 = 1100 was (60) 
r2 = 1100 was (-20) 

在Brian的情況下,表達式結果的大小是8; Verilog將擴展您的操作數以佔用8位空間。在簽約的情況下,「一」,它會唱歌擴展它,這將會使的區別:

unsigned a[3:0] <1100> --> tmp[7:0] --> 00001100 
signed a[3:0] <1100> --> tmp[7:0] --> 11111100 

因此,如果[3]爲「1」,它被認爲是一個標誌,並得到跡象升爲剩下。現在,您的算術看起來如下:

unsigned: tmpa(00001100) * tmpb(00000101) --> 00111100 
signed: tmpa(11111100) * tmpb(00000101) --> 11101100 

當顯示所述第二結果爲整數,則尚未被符號擴展到32位,並且將顯示爲(-20)

相關問題