- 依照目前與先前位元的不同,執行下面工作:
- 00: 字串0的中間部份,不需要算術運算
- 01: 字串1的結尾,所以將被乘數加到乘積的左半部
- 10: 字串1的開端,所以從乘積的左半部減去被乘數
- 11: 字串1的中間部份,所以不需要算術運算
- 如同前面的演算法,將乘積暫存器右移1位元
//16-bit Booth's algorithm for multiplier
//Filename : booth.v ;;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
module booth(A, B, P);
parameter width=16; //設定為16位元
input [width-1:0] A; //被乘數
input [width-1:0] B; //乘數
output [width+width-1:0] P; //乘積結果
reg [width+width-1:0] P;
integer Count; //右移次數
reg [width+width:0] PA,right; //暫存乘數
always @ (A or B)
begin
PA[width+width:0]={16'b0,A,1'b0}; //{P, A, 1'b0}
for(Count=0;Count<width;Count=Count+1)
begin
case(PA[1:0]) //用PA最後2bit用CASE選擇函數;(PA[1:0])
2'b10: //若PA[1:0]為10時
begin
//PA=PA-B ;當PA=10時,乘積=乘積-被乘積
PA[width+width:width+1]=PA[width+width:width+1] - B[width-1:0];
rightsh1(PA,right); //執行算數右移task副程式
end
2'b01: //若PA[1:0]為01時
begin
//PA=PA+B
PA[width+width:width+1]=PA[width+width:width+1] + B[width-1:0];
rightsh1(PA,right); //執行算數右移task副程式
end
default: //若PA[1:0]為00或11時
rightsh1(PA,right); //直接執行算數右移task副程式
endcase
PA=right;
end
P[width+width-1:0]=PA[width+width:1]; //將乘積指定給輸出端
end
//右移task副程式
task rightsh1;
input [width+width:0] PA; //輸入為PA
output [width+width:0] right; //輸出為right
case (PA[width+width])
//最高位元為0時之算數右移
1'b0:right[width+width:0]={1'b0,PA[width+width:1]};
//最高位元為1時之算數右移
1'b1:right[width+width:0]={1'b1,PA[width+width:1]};
endcase
endtask
endmodule
沒有留言:
張貼留言