1. 程式人生 > 其它 >【Verilog】表示式位寬與符號判斷機制

【Verilog】表示式位寬與符號判斷機制

緣起於p1課下alu算數位移設計。查了好多資料,最後發現還是主要在翻譯官方文件。浪費了超多時間啊,感覺還是沒搞透,還是先以應用為導向放一放,且用且歸納

1.表示式位寬 expression bit length

身為硬體描述語言,Verilog表示式運算過程中必然要嚴肅考慮位寬問題

表示式的位寬由式中運算元和語境決定

表示式按位寬確定方式分為兩類:

  • self-determined expression
    位寬僅有表示式自身確定,不會受語境影響也不影響語境中其他表示式(在複合表示式中某些位置上的子表示式,如i>>j中的表示式ji?j:k中的表示式i)。
  • context-determined expression

    位寬由表示式本身和其所屬表示式(父子表示式)共同決定(如阻塞賦值操作的RHS位寬由其自身和LHS被賦值變數的位寬決定)。

下表中i,j,k表示"單運算元表示式",L(i)表示表示式i的位寬

截自verilog-std-1364-2005

有些根本性的理解不是很到位

例1:所謂中間值位寬

例2:三元運算子表示式位寬

例3:綜合由語境決定位寬

2.表示式符號性 expression signedness

Verilog計算表示式前,需要確定表示式的符號性,規則如下:

  • 僅取決於RHS運算元,與LHS無關(與位寬確定有別,如assign a = b ? c : d;中LHS符號性與a自身無關)
  • 十進位制數視為signed
  • 進製表示數視為unsigned,除非使用進位制前加s特殊標明(4'd3無符號,4'sd3無符號)
  • 位選擇(不論是否選全)、位拼接(不論運算元)結果視為unsigned
  • 比較表示式結果視為unsigned
  • 實數強轉整形表示式結果視為signed
  • self-determined expression:符號性取決於其中運算元
  • context-determined expression:
    • 若存在運算元為real,則結果視為real
      • 若存在運算元為unsigned,則結果視為unsigned
      • 若所有運算元為signed,則結果視為signed
  • 變數本身是unsigned(不過存了01串罷了,不要因為reg [3:0]a = 2'sb11
    就認為變數a是signed),除非宣告時附加關鍵字signed

確定整個表示式的符號性後,便會向內層表示式傳遞符號性,直至各運算元。
$signed(exp)函式計算傳入的exp並返回與其值和位寬均相同的資料,將其符號性改為signed。可以看作遮蔽了外部表示式的符號性傳遞。

例:含三元運算子的表示式

testbench中使ALUop恆為3'd5A=4'b1101

input [3:0] A,
input [3:0] B,
input [2:0] ALUOp,
output [3:0] C
assgin C = (ALUOp == 3'd5) ? A >>> B : 4'sd0;

分析
在三元運算子(ALUop == 3'd5)屬於self-determined表示式,不會影響符號性判斷。因而看後半部分。4'sd0為符號數;A >>> B表示式中B為self-determined表示式(運算元),所以符號性僅看AA無符號,因而總表示式RHS無符號。

傳遞符號性後,A無符號數經算數位移值為4'b0110,再賦給C

assgin C = (ALUOp == 3'd5) ? $signed(A) >>> B : 4'sd0;

分析
$signed()使$signed(A)表示式有符號,則$signed(A) >>> B表示式有符號,則總表示式RHS有符號。

傳遞符號性後,$signed(A)A相當於被$signed()隔絕,仍無符號)被視為有符號數,算數位移後值為4'b1110

assgin C = (ALUOp == 3'd4) ? A + B :
           (ALUOp == 3'd5) ? $signed(A) >>> B : 4'sd0 ;

分析
巢狀式三元運算子的結構。A + B表示式無符號(其中中AB無符號),因而總表示式RHS無符號。

傳遞符號性:(ALUOp == 3'd5) ? $signed(A) >>> B : 4'sd0無符號;$signed(A) >>> B無符號;$signed(A)無符號(A$signed()保護),算數位移後值為4'b0110

assgin C = (ALUOp == 3'd4) ? A + B :
           (ALUOp == 3'd5) ? $signed($signed(A) >>> B) : 4'sd0 ;

分析
同上,總表示式RHS無符號。

傳遞符號性:(ALUOp == 3'd5) ? $signed(A) >>> B : 4'sd0無符號;$signed($signed(A) >>> B)無符號。$signed(A) >>> B被保護,因而$signed(A)仍視為有符號,算數位移後值為4'b1110