程序代码如下:
方法一
module Booth_multiplier (mul_a, mul_b, clk, rst_n,start, mul_out);
input [7:0] mul_a, mul_b;
input clk;
input rst_n;
input start;
output [15:0] mul_out;
reg [15:0] i;
reg [15:0] j;
reg [7:0] mul_ax;
reg [16:0] mul_bx;
reg [15:0] mul_out;
always @ ( posedge clk or negedge rst_n )
begin
if(!rst_n)
begin
i<=0;
j<=0;
mul_bx<=0;
mul_out<=0;
end
else begin
if(start==1)
case(i)
0:
begin
mul_bx <= {8'b0,mul_b,1'b0};
mul_ax <= ~mul_a+1'b1;
i <= 2;
end
1:
begin
if(mul_bx[16]==1)
begin
mul_bx<={1'b1,mul_bx[16:1]};
end
else if(mul_bx[16]==0)
begin
mul_bx<={1'b0,mul_bx[16:1]};
end
i <= 2;
end
2:
begin
if({mul_bx[1],mul_bx[0]}==2'b10)
begin
mul_bx <= mul_bx + {mul_ax,9'b0};
end
else if({mul_bx[1],mul_bx[0]}==2'b01)
begin
mul_bx <= mul_bx + {mul_a,9'b0};
end
i<=3;
end
3:
begin
j = j+1'b1;
if(j<8)
begin
i<=1;
end
else
begin
i<=4;
end
end
4:
begin
if(mul_bx[16]==1)
begin
mul_bx<={1'b1,mul_bx[16:1]};
end
else if(mul_bx[16]==0)
begin
mul_bx<={1'b0,mul_bx[16:1]};
end
i<=5;
end
5:
begin
mul_out = mul_bx[16:1];
end
endcase
end
end
endmodule
方法二
module Booth (mul_a, mul_b, clk, rst_n,start, mul_out);
input [7:0] mul_a, mul_b;
input clk;
input rst_n;
input start;
output [15:0] mul_out;
reg [15:0] mul_out;
reg [4:0] i;
reg [3:0] n;
reg [7:0] A;
reg [8:0] B;
reg [2:0] xx;
reg [7:0] y;
reg [15:0] y_out;
reg [15:0] out;
always @ ( posedge clk or negedge rst_n )
begin
if(!rst_n)
begin
i<=0;
n<=0;
A<=0;
B<=0;
mul_out<=0;
xx<=0;
y<=0;
y_out<=0;
out<=0;
end
else
begin
if(start==1)
begin
case(i)
0:
begin
n<=0;
B<={mul_b,1'b0};
A<=mul_a;
i<=1;
end
1:
begin
xx=B[n+2-:3];
case(xx)
3'b000:y=0;3'b111:y=0;3'b001:y=A;3'b010:y=A;3'b011:y={A[6:0],1'b0};
3'b101:y=~A+1'b1;3'b110:y=~A+1'b1;3'b100:y=~{A[6:0],1'b0}+1'b1;
endcase
i=2;
end
2:
begin
case(n)
4'b0000:
begin
if((xx==3'b101)||(xx==3'b110)||(xx==3'b100))
begin
y_out={8'b1111_1111,y};
end
else
begin
y_out={8'b0000_0000,y};
end
end
4'b0010:
begin
if((xx==3'b101)||(xx==3'b110)||(xx==3'b100))
begin
y_out={6'b1111_11,y,2'b11};
end
else
begin
y_out={6'b0000_00,y,2'b00};
end
end
4'b0100:
begin
if((xx==3'b101)||(xx==3'b110)||(xx==3'b100))
begin
y_out={4'b1111,y,4'b1111};
end
else
begin
y_out={4'b0000,y,4'b0000};
end
end
4'b0110:
begin
if((xx==3'b101)||(xx==3'b110)||(xx==3'b100))
begin
y_out={2'b11,y,6'b1111_11};
end
else
begin
y_out={2'b00,y,6'b0000_00};
end
end
endcase
out=out+y_out;
n=n+2;
if(n==4'b1000)
begin
i=3;
end
else
begin
i=1;
end
end
3:
begin
mul_out=out;
end
endcase
end
end
end
endmodule
测试代码:
`timescale 1ns/1ns
module Booth_multiplier_tb();
reg [7:0] A,B;
reg clk;
reg rst_n;
reg start;
wire [15:0] S;
initial begin
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=4;B=6;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=3;B=5;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=10;B=20;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=32;B=15;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=21;B=80;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
clk = 0;
rst_n=0;
start=0;
#100
rst_n=1;
start=1;
A=40;B=5;
#100
$display("\tA=%b,B=%b,S=%b",A,B,S);
$stop;
end
always #1 clk = ~clk;
Booth_multiplier U(A,B,clk,rst_n,start,S);
endmodule