本队伍号为CICC3152,booth4乘法器有其独特的算法原理,实现同位数乘法可以花费更少的时钟周期,因此蜂鸟e203内部执行单元也是采用此种乘法。笔者参照原理自行写了一下,具体原理大家可以网上了解,这里抛砖引玉一下。
///有符号数的booth_4乘法 A*B
//{两个符号位,A,B,0}
module booth_4 #(
parameter witdh_a = 8 ,
parameter witdh_b = 8
)
(
input clk ,
input rstn ,
input start ,
input [witdh_a-1:0] A ,
input [witdh_b-1:0] B ,
output [witdh_a+witdh_b-1:0] result,
output done
);
reg [witdh_a+witdh_b+2:0] pc ;
reg done_reg ;
reg [witdh_a+witdh_b-1:0] result_reg ;
parameter IDLE = 2'b00 ,
ADD = 2'b01 ,
SHIFT= 2'b11 ,
OUTPUT=2'b10 ;
reg [1:0] current_state ;
reg [1:0] next_state ;
always@(posedge clk or negedge rstn)
begin
if(!rstn) begin
current_state <= IDLE ;
end else if (start) begin
current_state <= next_state ;
end else begin
current_state <= IDLE ;
end
end
reg [witdh_b-1:0] count ;
always@*
begin
case(current_state)
IDLE: if(start) begin next_state <= ADD; end
else next_state <= IDLE ;
ADD : next_state <= SHIFT;
SHIFT: if(count==witdh_b/2) begin next_state <= OUTPUT; end
else next_state <= ADD ;
OUTPUT: next_state <= IDLE;
default:next_state <= IDLE;
endcase
end
reg [witdh_a+1:0] a ;
reg [witdh_a+1:0] a_buma ;
reg [witdh_a+1:0] ax2 ;
reg [witdh_a+1:0] ax2_buma ;
always@(posedge clk or negedge rstn)
begin
if(!rstn) begin
{a_buma,ax2,ax2_buma,pc,done_reg} <= 0 ;
end else begin
case(current_state)
IDLE:begin
pc <= {{witdh_a+2{1'b0}},B,1'b0} ;
a <= {{2{A[witdh_a-1]}},A} ;
a_buma <= {~{{2{A[witdh_a-1]}},A}+1'b1} ;
ax2 <= {A[witdh_a-1],A,1'b0} ;
ax2_buma <= {~{A[witdh_a-1],A,1'b0}+1'b1} ;
count <= 0 ;
done_reg <= 0 ;
end
ADD: begin
case(pc[2:0])
3'b000,3'b111:begin pc <= pc; end //无操作
3'b001,3'b010:begin pc <= {pc[witdh_a+witdh_b+2:witdh_b+1]+a,pc[witdh_b:0]}; end //+A
3'b101,3'b110:begin pc <= {pc[witdh_a+witdh_b+2:witdh_b+1]+a_buma,pc[witdh_b:0]}; end //-A
3'b011: begin pc <= {pc[witdh_a+witdh_b+2:witdh_b+1]+ax2,pc[witdh_b:0]}; end //+2A
3'b100: begin pc <= {pc[witdh_a+witdh_b+2:witdh_b+1]+ax2_buma,pc[witdh_b:0]}; end //-2A
endcase
count <= count + 1 ;
end
SHIFT: begin
pc <= {pc[witdh_a+witdh_b+2],pc[witdh_a+witdh_b+2],pc[witdh_a+witdh_b+2:2]} ;
end
OUTPUT:begin
done_reg <= 1;
result_reg <= pc[witdh_a+witdh_b:1] ;
end
endcase
end
end
assign result = result_reg ;
assign done = done_reg ;
endmodule