1. 乘法器实现原理
计算N位二进制数的乘法,需要N次循环,每次执行以下操作:
- 查看乘数的最低位。
- 如果乘数最低位是1,积加上被乘数
- 被乘数左移一位,乘数右移一位
流程图示意如下(64位为例):
2. Verilog代码
' //设计32位加法器
module mul32(
input clk,
input rst,
input [31:0]multiplicand, //multiplicand
input [31:0]multiplier, //multiplier
input start, //the calculation begin
output reg[64:0] product, //final result
output finish //the calculation finishes
);
reg [1:0]flag;
reg [5:0]cnt;
integer i;
initial begin
flag <= 0;
cnt <= 6'b0;
product <= 65'b0;
end
always@(posedge clk or posedge rst)begin
if(rst == 1) begin
cnt = 6'b0;
product = 65'b0;
flag <= 0;
end
if(clk) begin
if(start == 1) begin //read multiplier
product [31:0] = multiplier;
cnt = 0;
flag[0] = 1;
flag[1] = 0;
end //start calculate
else begin
if(flag[0] == 1) begin
if(cnt == 31) begin //End the cycle
flag = 2'b10;
cnt = 0;
end
if(product[0] == 1) begin
product[64:32] = product[64:32] + multiplicand;
end
product = product >> 1;
cnt = cnt + 1;
end
end
end
end
assign finish = flag[1]; //end flag
endmodule
3. 仿真代码(部分)
initial begin
clk = 0;
rst = 1;
multiplicand = 0;
multiplier = 0;
start = 0;
#100
/*test 1*/
rst = 0;
start = 1; //start = 1:Initialization the value
multiplicand = 32'd2;
multiplier = 32'd3;
#350
start = 0; //start = 0:Start calculation
#350
/*test 2*/
start = 1;
multiplicand = 32'd10;
multiplier = 32'd8;
#350
start = 0;
#350
/*test 3*/
start = 1;
multiplicand = 32'd9;
multiplier = 32'd9;
#350
start = 0;
#350
/*test 4*/
start = 1;
multiplicand = 32'd50;
multiplier = 32'd6;
#350
start = 0;
#350
/*test 5*/
start = 1;
multiplicand = 32'd6;
multiplier = 32'd60;
#350
start = 0;
#350
/*test 6*/
start = 1;
multiplicand = 32'hFFFFFFFF;
multiplier = 32'hFFFFFFFF;
#350
start = 0;
#350
#4000 $finish();
end
always #5 clk = ~clk;
-
验证1: 2 × 3 = 6 2\times 3 = 6 2×3=6
-
验证2: 10 × 8 = 80 10 \times 8 = 80 10×8=80
-
验证3: 9 × 9 = 81 9 \times 9 = 81 9×9=81
-
验证4: 50 × 6 = 300 50\times 6 = 300 50×6=300
-
验证5: 6 × 60 = 360 6\times 60 = 360 6×60=360
-
验证6: 0 x f f f f f f f × 0 x f f f f f f f = 0 x f f f f f f f e 00000001 0xfffffff \times 0xfffffff = 0xfffffffe00000001 0xfffffff×0xfffffff=0xfffffffe00000001