最近做了一个布思基四乘法器,综合和功能仿真通过. 能够实现正负数直接相乘(乘数和被乘数全部用补码表示,乘积也是补码).以下是代码.
[说明:]仿真时需要注意一下信号间的时序要求.start信号相对于时钟信号有建立和保持时间的限制,同样word1,word2信号相对于start也有建立和保持时间的限制.
module multiplier_booth_radix_4(product,ready,word1,word2,start,reset,clk);
parameterL_word=8;
parameterS_idle=0,S_running=1,S_adding=2,S_subing=3;
parameterAll_ones=8'b1111_1111;
output [2*L_word-1:0] product;
outputready;
input[L_word-1:0]word1,word2;
inputstart,reset,clk;
reg[1:0]state,next_state;
regm0;
reg[2*L_word-1:0]product,multiplicand;
reg[L_word-1:0]multiplier;
regflush,shift_2,shift_1,add_shift_1,add_shift_2;
regsub_shift_1,sub_shift_2,load_words;
reg[2:0]count;
wire[2:0]BPEB={multiplier[1:0],m0};
wireready=(state==S_idle)&&(!reset);
wireempty=((word1==0)||(word2==0));
always@(posedge clk or posedge reset)//Datapath
begin
if(reset) begin
multiplicand<=0;
multiplier<=0;
product<=0;
m0<=0;
count<=0;
end
else if(flush)
product<=0;
else if(load_words) begin
m0<=0;
if(word1[L_word-1]==0) multiplicand<=word1;
else multiplicand<={All_ones,word1[L_word-1:0]};
multiplier<=word2;
product<=0;
end
else if(shift_2) begin
count<=count+1;
multiplicand<=multiplicand<<2;
{multiplier,m0}<={multiplier,m0}>>2;
end
else if(shift_1) begin
multiplicand<=multiplicand<<1;
{multiplier,m0}<={multiplier,m0}>>1;
end
else if(add_shift_2) begin
count<=count+1;
product<=product+multiplicand;
multiplicand<=multiplicand<<2;
{multiplier,m0}<={multiplier,m0}>>2;
end
else if(sub_shift_2)begin
count<=count+1;
product<=product-multiplicand;
multiplicand<=multiplicand<<2;
{multiplier,m0}<={multiplier,m0}>>2;
end
else if(add_shift_1) begin
count<=count+1;
product<=product+multiplicand;
multiplicand<=multiplicand<<1;
{multiplier,m0}<={multiplier,m0}>>1;
end
else if(sub_shift_1)begin
count<=count+1;
product<=product-multiplicand;
multiplicand<=multiplicand<<1;
{multiplier,m0}<={multiplier,m0}>>1;
end
if(count==4) count<=0;
end
always@(posedge clk or posedge reset)//state transition
if(reset)
state<=S_idle;
else
state<=next_state;
always@(state or start or BPEB or multiplier or empty or count)//state machine
begin
load_words=0;
shift_2=0;
shift_1=0;
add_shift_2=0;
add_shift_1=0;
sub_shift_2=0;
sub_shift_1=0;
flush=0;
case(state)
S_idle:if(!start) next_state=S_idle;
else if(start&&!empty) begin
load_words=1; next_state=S_running;
end
else if(start&&empty) begin
flush=1; next_state=S_idle;
end
S_running: if(count==4) next_state=S_idle;
else if(BPEB==3'b000||BPEB==3'b111) begin shift_2=1;next_state=S_running; end
else if(BPEB==3'b001||BPEB==3'b010) begin add_shift_2=1; next_state=S_running; end
else if(BPEB==3'b101||BPEB==3'b110) begin sub_shift_2=1; next_state=S_running; end
else if(BPEB==3'b011) begin shift_1=1; next_state=S_adding; end
else if(BPEB==3'b100) begin shift_1=1; next_state=S_subing; end
S_adding:begin add_shift_1=1; next_state=S_running; end
S_subing:begin sub_shift_1=1; next_state=S_running; end
default:next_state=S_idle;
endcase
end
endmodule