[说明:]仿真时需要注意一下信号间的时序要求.start信号相对于时钟信号有建立和保持时间的限制,同样word1,word2信号相对于start也有建立和保持时间的限制.
module multiplier_booth_radix_4(product,ready,word1,word2,start,reset,clk);
parameter L_word=8;
parameter S_idle=0,S_running=1,S_adding=2,S_subing=3;
parameter All_ones=8'b1111_1111;
output [2*L_word-1:0] product;
output ready;
input [L_word-1:0] word1,word2;
input start,reset,clk;
reg [1:0] state,next_state;
reg m0;
reg [2*L_word-1:0] product,multiplicand;
reg [L_word-1:0] multiplier;
reg flush,shift_2,shift_1,add_shift_1,add_shift_2;
reg sub_shift_1,sub_shift_2,load_words;
reg [2:0] count;
wire [2:0] BPEB={multiplier[1:0],m0};
wire ready=(state==S_idle)&&(!reset);
wire empty=((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