[DSP with spinalHDL] 00 數的表示與位數變化

在FPGA中能夠自定義數位寬,這帶來了極大的靈活性(相較於C語言等其餘語言),可是同時帶來的問題就是如何解讀這些數據,以及如何處理好他們的進位關係。(以前的某個項目中,就是由於計算位數錯誤,致使項目結果的錯誤,debug好久)所以寫下這篇blog,對這部分做出必定的總結。git

數的表示

目前我經常使用的是unsigned int,signed int 以及 fixed-point三種。下面分別介紹。github

Unsigned int

這種是最最簡單的表示方法。debug

一列數:code

\(a_n a_{n-1}... a_2 a_1a_0\)blog

他的大小等於get

\(D=\sum_{i=0}^{n} a_i 2^i\)it

如: b11100111module

其大小等於 
\(2^7+2^6+2^5+2^2+2^1+2^0=231\)語法

Signed int

很是常見的有符號整數的表示方法,一般的ADC的輸出就是這種形式。一般是用補碼錶示。bug

最高位爲符號位,剩下的部分表示數字

定義是這樣的:

  • 正數的補碼等於原碼
  • 負數的補碼=負數的反碼+1
  • 負數的反碼=符號位爲1,剩下的部分爲正數的取反

若是暈了就看下面的例子

比方說-3用8位Signed int表示爲

# 3的Signed int
0000_0011
# 3的反碼
1111_1100
# 3的補碼
1111_1101   # 爲0xfd

驗證一下:

module invert(
	output signed [7:0] out,
	output signed [7:0] out1,
	);
    assign out = -3;
    assign out1 = 3;

    `probe(out);   // 這個是iverilog用於實現波形的語法
    `probe(out1); 
endmodule

結果爲:

image

Fixed point

定點數顧名思義就是小數點的位置在二進制數中是固定的,一般須要本身定義。

如總位寬8位的,3位小數,1位符號位表示爲,其中\(\Delta\)表示小數點

\(S_4 a_3 a_2 a_1 a_0 \Delta a_{-1} a_{-2} a_{-3}\)

原碼的話,計算方式同Unsigned int

\(D=(-1)^{S_4}\sum_{i=-3}^{3} a_i 2^i\)

反碼、補碼都同Signed int,注意補碼在最低位+1

舉例: -1.75 Fixed point 總位寬8位的,3位小數,1位符號位表示爲

# 原碼
1 0001.110
# 反碼
1 1110.001
# 補碼
1 1110.010  # 0xf2

驗證:verilog自己不支持Fixed point,這裏採用更加高級的SpinalHDL來驗證,具體關於SpinalHDL的能夠本身看看

image

數的表示,特別是負數的表示,採用補碼的形式,這種方式更容易計算加減法,而採用原碼的表示,更容易計算乘法。

計算時位數的變化

在運算的時候 位寬是會變化的,所以須要注意變化的規律

加減

在兩個位寬爲B的加減運算中,要保證數據不溢出,結果的位寬應爲B+1

在SpinalHDL中,採用 +^ 或 -^ 來保證自動推斷位寬

image

乘法結果的位寬等於被乘數兩個位寬之和

image

除法儘可能使用IP覈實現

相關文章
相關標籤/搜索