在數字邏輯系統,僅僅存在高低。所以用它只代表一個整數數字。并且有3代表性的種類。這是:原碼表示(符號加絕對值值)、反碼表示(加-minus標志)而補碼(符號加補)。這三個在FPGA中都有著廣泛的應用。以下分別討論。
1、原碼表示法
原碼表示法是機器數的一種簡單的表示法。採用符號位級聯絕對值的方法表示數字。其最高位為符號位,用0表示正數,1表示負數;其余部分為絕對數值部分。原碼一般用二進制形式表示。
比如,X1 = +1010110,X2 = -1001010,則其原碼分別為:01010110和11001010
原碼表示數的范圍與二進制位數有關。當用8位二進制來表示小數原碼時,其表示范圍:最大值為0.1111111,其真值約為10進制中的0.99;最小值為1.1111111。其真值約為十進制的-0.99。
當用8位二進制來表示整數原碼時。其表示范圍:最大值為01111111。其真值為十進制的127;最小值為11111111。其真值為十進制的-127。
在原碼表示法中。對0有兩種表示形式,分別記為+0和-0,以8比特數據為例,其對應的表示為:+0=00000000、-0=10000000。
2、反碼表示法
反碼可由原碼得到。
假設數字是正數,則其反碼與原碼一樣。假設數字是負數,則其反碼是對它的原碼(符號位除外)各位取反而得到的。
比如:X1 = +1010110, X2=-1001010,則其對應的反碼為01010110、10110101。
3、補碼表示法
補碼表示法師實際中應用最廣泛的數字表示法。其表示規則例如以下:若是正數。補碼、反碼和原碼的表示是一樣的。若是負數,補碼、反碼和原碼的表示都不一樣。
由反碼與原碼之間的關鍵,負數的補碼等于其反碼在最低位加1。
4、各類表示方法小結
原碼的長處就是乘除運算方便。不論正負數,乘除運算都一樣,并以符號位決定結果的正負號;若做加法則須要推斷兩數符號是否同樣。若作減法,還須要推斷兩數絕對值的大小,以使大數減小數。
補碼的長處是。加法運算方便,不論數的正負都可直接相加。而符號位相同參加運算。
例:給出各類碼字表示法的基本加法運算實例,并說明各自特點
(1)首先給出原碼的運算演示樣例。當中()d代表十進制數。
首先給出一個原碼的減法計算實例,完畢“1 + (-1)= 0“”的操作。
(1)d + (-1)d = (0)d
假設讀者直接利用原碼來完畢上式運算,會發現用符號位的原碼進行在加減運算的時候就會出現故障。將數據以8比特的表示形式為例,
(00000001)原 + (10000001)原 = (10000001)原 = (-2)d
計算結果是不對的,問題在于兩點:首先。負數的符號位直接改變了計算結果符號;其次,絕對值部分計算也不對。
這說明原碼無法直接完畢正數和負數的加法。
(2)既然,原碼不能完畢正、負數相加。那么反碼形式能夠完畢此操作嗎?仍然以”1 + (-1) = 0“ 為例,其對應的反碼表達式例如以下:
(00000000)反 + (11111110)反 = (11111111)反 = (-0)d
則發現問題出如今+0和-0上。由于實際的計算中的零沒有正負之分的。但上式標明了反碼完畢正、負數相加后。其絕對值部分是正確的。因此能正確完畢正、負數相加的表達形式必然包括反碼的特性。
(3)最后給出補碼的相關特性說明,負數的補碼就是對反碼加1,而正數不變。
以8比特數據為例。通過(-128)d取代了(-10)d。所以其表示范圍為【-128,127】。從直觀上。補碼消除了(+0)和(-0)。而且具備反碼特點,那么到底其能完畢正、負加法運算嗎?答案是肯定的,以下給出詳細實例,所看到的
(00000001)補 + (11111111)補 = (00000000)補 = (0)d
基于以上討論,能夠得到一個基本結論:僅僅有補碼才干正確完畢正負加法運算,并將減法運算轉化為加法運算,從而簡化運算規則。
但對于乘法操作。則以原碼形式計算是最方便的。以下有實例。
演示1:原碼進行乘法運算 -2 * 2 = -4
module mul(input clk,input rstn,input [7:0] a,input [7:0] b,output [14:0] q_mul,output reg [8:0] q_add,output reg[7:0] ra,output reg[7:0] rb);reg [13:0] rmul;always @(posedge clk or negedge rstn)if(!rstn)beginq_add <= 0;ra <= 0;rb <= 0;rmul <= 0;endelse begin//q_mul <= a*b;if(a[7]==1)ra = {a[7],~a[6:0] + 1};elsera = a;if(b[7]==1)rb = {b[7],~b[6:0] + 1};elserb = b;rmul <= ra[6:0]*rb[6:0];q_add <= {a[7],a} + {b[7],b};endassign q_mul = {a[7]^b[7],rmul};endmodule
演示2:通過reg signed實現
module signedMul(input clk,input rstn,input [7:0] a,input [7:0] b,output [15:0] q);reg signed[7:0] ra;reg signed[7:0] rb;always @(posedge clk or negedge rstn) beginif(~rstn) beginra <= 0;rb <= 0;endelse beginra <= a;rb <= b;endendassign q = ra * rb;endmodule
版權聲明:本文博主原創文章,博客,未經同意不得轉載。