原碼1位乘法
在定點計算機中,兩個原碼表示的數相乘的運算規則是:乘積的符號位由兩數的符號按異或運算得到。而乘積的數值部分則是兩個正數相乘之積。設n位被乘數和乘數用定點小數表示(定點整數也相同適用)
被乘數 [x]原 = xf .x0 x1 x2 … xn
乘數 [y]原 = yf .y0 y1 y2 … yn
則
乘積 [ z ]原 = ( xf⊕yf ) . (0. x0 x1 x2 …xn)(0 . y1 y2 …yn)
式中,xf為被乘數符號。yf為乘數符號。
乘積符號的運算法則是:同號相乘為正,異號相乘為負。因為被乘數和乘數和符號組合僅僅有四種情況(xf yf = 00,01,10,11),因此積的符號可按“異或”(按位加)運算得到。
數值部分的運算方法與普通的十進制小數乘法相類似。只是對於用二進制表達的數來說,其乘法規則更為簡單一些:從乘法y的最低位開始。若這一位為“1”。則將被乘數x寫下;若這一位為“0”,則寫下全0。然后再對乘數y的高一位進行的乘法運算,其規則同上,只是這一位乘數的權與最低位乘數的權不一樣。因此被乘數x要左移一位。依次類推。直到乘數各位乘完為止。最后將它們統統加起來。便得到最后乘積z 。
設 x = 0.1011。y = 0.1101,讓我們先用習慣方法求其乘積。其步驟例如以下:
× |
|
|
|
|
|
0. |
1 |
1 |
0 |
1 |
(x) |
|
0. |
1 |
0 |
1 |
1 |
(y) |
|||||
+ |
|
|
|
|
|
|
1 |
1 |
0 |
1 |
|
|
|
1 |
1 |
0 |
1 |
|
|||||
|
0 |
0 |
0 |
0 |
|
|
|||||
1 |
1 |
0 |
1 |
|
|
|
|||||
|
|
0. |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
(z) |
假設被乘數和乘數用定點整數表示,我們也會得到相同的結果。可是。可是人們習慣的算法對機器並不全然適用。原因之中的一個,機器通常僅僅有n位長,兩個n位數相乘,乘積可能為2n位。原因之二,僅僅有兩個操作數相加的加法器,難以勝任將n個位積一次相加起來的運算。為了簡化結構,機器通常僅僅有n位長。而且僅僅有兩個操作數相加的加法器。為此,必須改動上述乘法的實現方法。將 x · y 改寫成適於例如以下定點機的形式:
一般而言。設被乘數 x 、乘數 y 都是小於 1 的 n 位定點正數:
x = 0 . x1 x2 … xn 。 y = 0 . y1 y2 … yn
其乘積為
x · y = x · ( 0.y1y2 … yn )
= x · ( y1 2 -1 + y2 2 -2 + … + yn 2 -n)
= 2 -1( y1x + 2-1( y2 x + 2-1 (… + 2-1 ( yn-1 x + )…))
令 zi 表示第 i 次部分積,則上式可寫成例如以下遞推公式:
z0 = 0
z1 = 2-1( ynx + z0)
…
zi = 2-1( yn-i+1x + zi-1) (2.3.2)
…
zn = x·y = 2-1( y1x + zn-1)
顯然,欲求x·y,則需設置一個保存部分積的累加器。
乘法開始時,令部分積的初值z0 = 0。然后求加上ynx。右移1位得第1個部分積,又將加上yn - 1x,再右移1位得第2個部分積。依此類推。直到求得y1x加上zn-1並右移1位得最后部分積,即得x·y。顯然,兩個n位數相乘。需反復進行n次“加”及“右移”操作。才干得到最后乘積。這就是實現原碼一位乘法的規則。
【例 】 x = 0.1101。 y = 0.1011。用原碼一位乘法計算 x · y = ?
|
|
部分積 |
|
|
乘數 |
說明 |
|||||
|
|
|
00.0000 |
|
yf |
1 |
0 |
1 |
1 |
|
z0 = 0 |
|
+ |
|
00.1101 |
|
|
|
|
|
|
|
y4 = 1,+ x |
|
|
|
00.1101 |
|
|
|
|
|
|
|
|
|
|
→ |
00.0110 |
|
1 |
yf |
1 |
0 |
1 |
|
右移。得z1 |
|
+ |
|
00.1101 |
|
|
|
|
|
|
|
Y3 = 1。+ x |
|
|
|
01.0011 |
|
|
|
|
|
|
|
|
|
|
→ |
00.1001 |
|
1 |
1 |
yf |
1 |
0 |
|
右移,得z2 |
|
+ |
|
00.0000 |
|
|
|
|
|
|
|
Y2 = 0,+0 |
|
|
|
00.1001 |
|
|
|
|
|
|
|
|
|
|
→ |
00.0100 |
|
1 |
1 |
1 |
yf |
1 |
|
右移,得z3 |
|
+ |
|
00.1101 |
|
|
|
|
|
|
|
Y1 = 1,+ x |
|
|
|
01.0001 |
|
|
|
|
|
|
|
|
|
|
→ |
00.1000 |
|
1 |
1 |
1 |
1 |
yf |
|
右移,得z3 = xy |
所以 x · y = 0.10001111
圖2-7 為實現原碼一位乘法的硬件邏輯原理圖。這里有三個寄存器,當中 R0 存放部分積z,在乘法開始 R0 前應清“0”, 保證 z0 = 0,R1 寄存器存放乘數 y ,R2寄存器存放被乘數 x 。因為乘法開始時先從乘數的最 低位 yn 開始,以后則使用yn - 1,yn - 2,…,y1,因此乘數寄存器 R1 應當是具有右移功能的移位寄存器。 假定加法器不具備右移功能,那么因為部分積須要右移,R0 也應當是具有右移功能的移位寄存器。 |
圖2-7 原碼一位乘法邏輯結構原理圖 |
除了三個寄存器 R0,R1,R2 外。還需一個加法器和一個計數器,前者完畢部分積與位積的累加,后者對移位的次數進行計數。以便推斷乘法運算是否結束。
乘法開始時,“啟動”信號使控制觸發器 Cx 置“1”。於是開啟時序脈沖 T 。當乘數寄存器 R0 最末位為“1”時,部分積 z 和被乘數 x 在加法器中相加。其結果輸出至 R0 的輸入端,一旦打入控制脈沖 T。控制信號 LDR0 使部分積右移 1 位,與此同一時候,乘數寄存器 R1 也在控制信號 LDR1 作用下右移一位,且計數器i計數 1 次。
當計數器 i = n 時。計數器i的溢出信號使控制觸發器 Cx 置“0”。關閉時序脈沖T,乘法操作結束。假設將 R0 和 R1 連接起來,乘法結束時乘積的高 n 位部分在 R0 ,低 n 位部分在 R1 。R1 中原來的乘數y因為右移而所有丟失,乘積為 2n+1 位,當中包含 1 位符號位。
補碼1位乘法
原碼乘法的主要問題是符號位不能參加運算,單獨用一個異或門產生乘積的符號位。
故自然提出是否能讓符號數字化后也參加乘法運算,補碼乘法就能夠實現符號位直接參加運算。
為了得到補碼一位乘法的規律。先從補碼和真值的轉換公式開始討論。
1. 補碼與真值的轉換公式
設 [x]補 = x0 . x1x2…xn ,有:
n | (2.3.3) |
x = - x0+∑ xi2-i | |
i=1 |
等式左邊 x 為真值。此公式說明真值和補碼之間的關系。
2. 補碼的右移
正數右移一位,相當於乘1/2(即除2)。
負數用補碼表示時。右移一位也相當於乘1/2。因此。在補碼運算的機器中,一個數不論其正負,連同符號位向右移一位。若符號位保持不變,就等於乘1/2。
3. 補碼乘法規則
設被乘數 [x]補 = x0.x1x2…xn 和乘數 [y]補 = y0.y1y2…yn 均為隨意符號,則有補碼乘法算式
n | (2.3.4) |
[ x · y ]補 = [x]補 · ( - y0 + ∑ yi2-i ) | |
i=1 |
為了推出串行邏輯實現人分步算法,將上式展開加以變換:
[x·y]補 = [x]補·[ - y0 + y12-1 + y22-2 + … + yn2-n]
= [x]補·[ - y0 + (y1 - y12-1) + (y22-1 - y22-2) + … + (yn2-(n-1) - yn2-n)]
= [x]補·[(y1 - y0) + (y2 - y1) 2-1 + … + (yn - yn-1) 2-(n-1) + (0 - yn)2-n]
= [x]補· (yn+1 = 0)
寫成遞推公式例如以下:
[ z0 ]補 = 0
[ z1 ]補 = 2 -1{ [ z0 ]補 + ( yn+1 - yn ) [x]補 } (yn+1 = 0)
…
[ zi ]補 = 2 -1{ [ zi-1 ]補 + ( yn-i+2 - yn-i+1 ) [x]補 } (2.3.5)
…
[ zn ]補 = 2 -1{ [ zn-1 ]補 + ( y2 - y1 ) [x]補 }
[ zn+1 ]補 = [ zn ]補 + ( y1 - y0 ) [x]補 = [ x · y ]補
開始時。部分積為 0。即 [z0]補 = 0。然后每一步都是在前次部分積的基礎上,由 ( yi+1 - yi ) ( i = 0。1,2。…,n) 決定對[x]補的操作,再右移一位。得到新的部分積。如此反復 n + 1步,最后一步不移位,便得到 [ x · y ]補 。這就是有名的布斯公式。
實現這樣的補碼乘法規則時。在乘數最末位后面要添加一位補充位 yn+1 。開始時,由 ynyn+1 推斷第一步該怎么操作。然后再由 yn - 1 yn 推斷第二步該怎么操作。由於每做一步要右移一位,故做完第一步后, yn - 1 yn 正好移到原來 ynyn+1 的位置上。依此類推,每步都要用 ynyn+ 1 位置進行推斷。我們將這兩位稱為推斷位。
假設推斷位 ynyn+1 = 01,則 yi+1 … yi = 1,做加[x]補操作。假設推斷位 yn yn+1 = 10,則 yi+1 … yi = - 1,做加[ - x]補 操作;假設推斷位 yn yn+1 = 11 或 00。則 yi+1… yi = 0。[ zi ] 加0。即保持不變。
4. 補碼一位乘法運算規則
(1) 假設 yn = yn+1,部分積 [ zi ] 加0。再右移一位;
(2) 假設 yn yn+1 = 01。部分積加[ x ]補。再右移一位;
(3) 假設 yn yn+1 = 10,部分積加[ - x]補,再右移一位;
這樣反復進行 n+1 步,但最后一步不移位。包含一位符號位,所得乘積為 2n+1 位,當中 n 為尾數位數。
【例 】 x = 0.1101。 y = 0.1011,用補碼一位乘法計算 x · y = ?
|
|
|
部分積 |
|
|
乘數 |
說明 |
||||
|
|
|
00.0000 |
|
0. |
1 |
0 |
1 |
1 |
0 |
yn+1 = 0 |
|
+ |
|
11.0011 |
|
|
|
|
|
|
|
ynyn+1 = 10,加[-x]補 |
|
|
|
11.0011 |
|
|
|
|
|
|
|
|
|
|
→ |
11.1001 |
|
1 |
0 |
1 |
0 |
1 |
1 |
右移一位 |
|
+ |
|
00.0000 |
|
|
|
|
|
|
|
ynyn+1 = 10,加0 |
|
|
|
11.1001 |
|
|
|
|
|
|
|
|
|
|
→ |
11.1100 |
|
1 |
1 |
0 |
1 |
0 |
1 |
右移一位 |
|
+ |
|
00.1101 |
|
|
|
|
|
|
|
ynyn+1 = 01,加[x]補 |
|
|
|
00.1001 |
|
|
|
|
|
|
|
|
|
|
→ |
00.0100 |
|
1 |
1 |
1 |
0f |
1 |
0 |
右移一位 |
|
+ |
|
11.0011 |
|
|
|
|
|
|
|
ynyn+1 = 01,加[-x]補 |
|
|
|
11.0111 |
|
|
|
|
|
|
|
|
|
|
→ |
11.1011 |
|
1 |
1 |
1 |
1 |
0 |
1 |
右移一位 |
|
+ |
|
00.1101 |
|
|
|
|
|
|
|
ynyn+1 = 01,加[x]補 |
|
|
|
00.1000 |
|
1 |
1 |
1 |
1 |
0 |
1 |
最后一步不移位 |
所以 [x · y]補 = 0.10001111
圖2-8 補碼一位乘法邏輯原理圖
實現一位補碼乘法的邏輯原理圖如圖 2-8 所看到的。它與一位原碼乘法的邏輯結構很類似,所不同的有下面幾點:
(1) 被乘數的符號和乘數的符號都參加運算。
(2) 乘數寄存器 R1 有附加位 yn+1 。其初始狀態為“0”。
當乘數和部分積每次右移時。部分積最低位移至 R1 的首位位置,故 R1 必須是具有右移功能的寄存器。
(3) 被乘數寄存器 R2 的每一位用原碼(即觸發器 Q 端)或反碼(即觸發器 Q 端)經多路開關傳送到加法器相應位的一個輸入端。而開關的控制位由和 yn 的 yn+1 輸出譯碼器產生。當ynyn+1 = 01時。送[x]補 ;當 ynyn+1 = 10 時,送[-x]補,即送的反碼且在加法器最末位上加“1”。
(4) R0 保存部分積。它也是具有右移功能的移位寄存器。其符號位與加法器 ∑f 符號位始終一致。
(5) 當計數器 i = n +1 時,封鎖 LD R0 和 LD R1 控制信號。使最后一位不移位。
運行補碼一位乘法的總時間為
tm = ( n + 1 ) ta + ntr | (2.3.6) |
當中 n 為尾數位數,ta 為運行一次加法操作的時間,tr 為運行一次移位操作的時間。假設加法操作和移位操作同一時候進行,則tr 項可省略。