- 一 設計思路
-
- (一)輸入、輸出
- (二)booth法運算規則
- (三)步驟
- 二 verilog代碼
-
- (一)程式代碼變量說明
- (二)程式代碼結構說明
-
- 1. 乘法器
- 2. 根據附加位和乘數末位進行加法操作
- 3. 移位
- 4. 截取最後一步的部分積和乘數作為輸出
- (三)程式代碼
- (四)時序模拟圖
一 設計思路
(一)輸入、輸出
-
輸入:兩個用補碼表示的二進制數(1位符号位+7位數值位)
[X]補 = X0.X1X2…X7
[Y]補 = Y0.Y1Y2…Y7
其中,X0、Y0為符号位。
- 輸出:兩個補碼相乘的結果(用補碼表示:1位符号位+14位數值位)
(二)booth法運算規則
Yi+1與Yi為相鄰的兩位
- Yi+1 - Yi = 0(即Yi+1Yi = 00或11):部分積加0,右移1位
- Yi+1 - Yi = 1(即Yi+1Yi = 10):部分積加[X]補,右移1位
- Yi+1 - Yi = -1(即Yi+1Yi = 01):部分積加[-X]補,右移1位
共需要做n+1次累加,n次位移,第n+1次(最後一步)不移位。
(三)步驟
- 輸入:單符号位補碼表示的x、y
-
初始化:依據輸入的x,得到雙符号位補碼表示的[x]補和[-x]補
初始部分積為0,附加位為0,乘數為輸入的y
- 依據booth公式,進行7次加法、移位操作。
- 最後進行1次加法操作,截取最後一步部分積和乘數相應位數,得到結果out。
二 verilog代碼
(一)程式代碼變量說明
input [7:0] x,y; // 輸入:補碼表示的乘數x和被乘數y,1位符号位+7位數值位
output [14:0] out; // 輸出:補碼表示的x×y的結果,1位符号位+14位數值位
wire [8:0] xx,_x; // xx:雙符号位[x]補,_xx:雙符号位[-x]補(2位符号位+7位數值位)
wire [8:0] partial_product[0:15]; // 雙符号位補碼表示的部分積(2位符号位+7位數值位),一次乘法運算過程中共需要16次對于部分積的操作(加、移位)
wire [7:0] multiplicator[0:7]; // 單符号位補碼表示的乘數(1位符号位+7位數值位),一次乘法運算過程中共需要8次對于部分積的操作(移位)
wire extra[0:7]; // 附加位,一次乘法運算過程中共需要8次對于附加位的操作(移位)
(二)程式代碼結構說明
1. 乘法器
module multiplier(x,y,out); // 乘法器
2. 根據附加位和乘數末位進行加法操作
module add( // 根據附加位和乘數末位進行加法操作
input [8:0] partial_product,xx,_x,
input [7:0] multiplicator,
input extra,
output [8:0] result);
3. 移位
module move( // 移位
input [8:0] partial_product_in,
input [7:0] multiplicator_in,
output [8:0] partial_product_out,
output [7:0] multiplicator_out,
output extra_out);
4. 截取最後一步的部分積和乘數作為輸出
module cut( // 截取最後一步的部分積和乘數作為輸出
input [8:0] partial_product,
input [7:0] multiplicator,
output [14:0] out);
(三)程式代碼
組合邏輯,booth法一位補碼乘法
軟體:Quartus II 9.0
module multiplier(x,y,out);
input [7:0] x,y; // 1 bit for sign + 7 bit for number
output [14:0] out; // 1 bit for sign + 14 bit for number
wire [8:0] xx,_x; // 2 bit for sign + 7 bit for number
wire [8:0] partial_product[0:15]; // 2 bit for sign + 7 bit for number
wire [7:0] multiplicator[0:7]; // 1 bit for sign + 7 bit for number
wire extra[0:7];
assign xx = {x[7],x};
assign _x = ~xx+1'b1;
assign partial_product[0] = 0;
assign multiplicator[0] = y;
assign extra[0] = 0;
add(partial_product[0],xx,_x,multiplicator[0],extra[0],partial_product[1]);
move(partial_product[1],multiplicator[0],partial_product[2],multiplicator[1],extra[1]);
add(partial_product[2],xx,_x,multiplicator[1],extra[1],partial_product[3]);
move(partial_product[3],multiplicator[1],partial_product[4],multiplicator[2],extra[2]);
add(partial_product[4],xx,_x,multiplicator[2],extra[2],partial_product[5]);
move(partial_product[5],multiplicator[2],partial_product[6],multiplicator[3],extra[3]);
add(partial_product[6],xx,_x,multiplicator[3],extra[3],partial_product[7]);
move(partial_product[7],multiplicator[3],partial_product[8],multiplicator[4],extra[4]);
add(partial_product[8],xx,_x,multiplicator[4],extra[4],partial_product[9]);
move(partial_product[9],multiplicator[4],partial_product[10],multiplicator[5],extra[5]);
add(partial_product[10],xx,_x,multiplicator[5],extra[5],partial_product[11]);
move(partial_product[11],multiplicator[5],partial_product[12],multiplicator[6],extra[6]);
add(partial_product[12],xx,_x,multiplicator[6],extra[6],partial_product[13]);
move(partial_product[13],multiplicator[6],partial_product[14],multiplicator[7],extra[7]);
add(partial_product[14],xx,_x,multiplicator[7],extra[7],partial_product[15]);
cut(partial_product[15],multiplicator[7],out);
endmodule
module add(
input [8:0] partial_product,xx,_x,
input [7:0] multiplicator,
input extra,
output [8:0] result);
wire [8:0] r1,r2;
assign r1 = (extra==multiplicator[0]) ? 0 : xx;
assign r2 = (!extra&multiplicator[0]) ? _x : r1;
assign result = partial_product + r2;
endmodule
module move(
input [8:0] partial_product_in,
input [7:0] multiplicator_in,
output [8:0] partial_product_out,
output [7:0] multiplicator_out,
output extra_out);
assign extra_out = multiplicator_in[0];
assign multiplicator_out = {partial_product_in[0],multiplicator_in[7:1]};
assign partial_product_out = {partial_product_in[8],partial_product_in[8:1]};
endmodule
module cut(
input [8:0] partial_product,
input [7:0] multiplicator,
output [14:0] out);
assign out = {partial_product[7:0],multiplicator[7:1]};
endmodule
(四)時序模拟圖
-
整數乘法
資料類型選Signed Decimal
verilog實作8位硬體乘法器(booth法補碼一位乘法)一 設計思路二 verilog代碼 -
定點小數乘法
資料類型選Fractional
verilog實作8位硬體乘法器(booth法補碼一位乘法)一 設計思路二 verilog代碼