下述乘法器是基于radix 4的booth乘法器,常用于集成电路IC的乘法器设计。
- 支持位宽可设置
- 支持signsign、signunsign、unsignsign、unsignunsign;
// +FHDR------------------------------------------------------------
// Copyright (c) 2023 COMPANY: Undefined variable..
// ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename : radix4_booth_mult.v
// Author :
// Created On :
// Last Modified :
// -----------------------------------------------------------------
// Description:
// radix 4 booth multipiler
// operate a can be int or uint, if(int) ,sign <= 1'b1 ,else sign <= 1'b0
// when multipiler used independently , op_b_cin <= 1'b0;
// when need to cascaded as WIDTH_A * (WIDTH_B*n) multipiler , op_b_cin <= (the highest bit of previous multipiler operate b)
//
// -FHDR------------------------------------------------------------
module radix4_booth_mult #(parameter WIDTH_A = 4,parameter WIDTH_B = 8
)(input wire comp_en //Take the complement of the calculation result,input wire sign_a //operate a sign flag,1'b1->signed,1'b0->unsigned,input wire sign_b //operate b sign flag,1'b1->signed,1'b0->unsigned,input wire [WIDTH_A-1:0] op_a //operate a data input,input wire [WIDTH_B-1:0] op_b //operate b data input,used to booth coding,input wire op_b_cin //booth coding carry in,when multipiler cascaded,use the highest bit of previous multipiler operate b,output reg [(WIDTH_A+WIDTH_B)*(WIDTH_B/2+2)-1:0] prod //wallace tree partial product output
);
//==============================================================================================
//====== function ========
//==============================================================================================//==============================================================================================
//====== parameter ========
//==============================================================================================localparam BOOTH_NUM = WIDTH_B/2;//==============================================================================================
//====== define signal ========
//==============================================================================================//reg complement ;reg signed_a ;reg signed_b ;reg [WIDTH_A-1:0] operate_a ;reg [WIDTH_B:0] operate_b ;wire [2:0] booth_code [BOOTH_NUM-1:0] ;wire [WIDTH_A+1:0] temp_prod [BOOTH_NUM-1:0] ;wire [BOOTH_NUM-1:0] temp_comp ;wire [(WIDTH_A+WIDTH_B)*(BOOTH_NUM+2)-1:0] prod_pre ;//==============================================================================================
//====== initialize signal ========
//==============================================================================================//==============================================================================================
//====== behave of RTL ========
//==============================================================================================//--------------------------------------------------------------------//------ buffer the input signal ------//--------------------------------------------------------------------always@(*)begin//complement = comp_en ;signed_a = sign_a ;signed_b = sign_b ;operate_a = op_a ;operate_b = {WIDTH_B+1{comp_en}}^{op_b,op_b_cin} ;end//--------------------------------------------------------------------//------ ------//--------------------------------------------------------------------genvar i;generate for(i=0;i<BOOTH_NUM;i=i+1) begin: distribute_aassign booth_code[i] = operate_b[i*2 +: 3];//assign booth_code[i] = {3{complement}} ^ operate_b[i*2 +: 3];booth #(.WIDTH(WIDTH_A)) u_booth_0 (.sign (signed_a ),.code (booth_code[i] ),.src_data (operate_a ),.out_data (temp_prod[i] ),.out_inv (temp_comp[i] ));assign prod_pre[(WIDTH_A+WIDTH_B)*i +: WIDTH_A+WIDTH_B] = {{(WIDTH_A+WIDTH_B-2*i-1){1'b0}},temp_prod[i],{2*i{1'b0}}};assign prod_pre[(WIDTH_A+WIDTH_B)*BOOTH_NUM + 2*i +: 2] = {1'b0,temp_comp[i]};end endgenerateassign prod_pre[(WIDTH_A+WIDTH_B)*BOOTH_NUM + WIDTH_B +: WIDTH_A] = (signed_b|(~operate_b[WIDTH_B]))? {WIDTH_A{1'b0}} : operate_a;assign prod_pre[(WIDTH_A+WIDTH_B)*(BOOTH_NUM+1) +: WIDTH_A+WIDTH_B] = {{BOOTH_NUM-1{2'b01}},2'b10,{WIDTH_A{1'b0}}};//--------------------------------------------------------------------//------ ------//--------------------------------------------------------------------always@(prod or prod_pre)beginprod = prod_pre ;end
endmodule//*******************************************************************************************//
//
//*******************************************************************************************//
// +FHDR------------------------------------------------------------
// Copyright (c) 2023 COMPANY: Undefined variable..
// ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename : booth.v
// Author :
// Created On :
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------module booth #(parameter WIDTH = 8
) (input sign,input [2:0] code,input [WIDTH-1:0] src_data,output reg [WIDTH+1:0] out_data,output reg out_inv
);
//==============================================================================================
//====== function ========
//==============================================================================================//==============================================================================================
//====== parameter ========
//==============================================================================================//==============================================================================================
//====== define signal ========
//==============================================================================================wire [WIDTH:0] data_in ;//==============================================================================================
//====== initialize signal ========
//==============================================================================================//==============================================================================================
//====== behave of RTL ========
//==============================================================================================assign data_in = {sign&src_data[WIDTH-1],src_data};always @(*) begincase(code)// +/- 0*src_data3'b000,3'b111:beginout_data = {1'h1,{WIDTH+1{1'h0}}};out_inv = 1'b0;end// + 1*src_data3'b001,3'b010:beginout_data = {~data_in[WIDTH], data_in};out_inv = 1'b0;end// - 1*src_data3'b101,3'b110:beginout_data = { data_in[WIDTH],~data_in};out_inv = 1'b1;end// + 2*src_data3'b011:beginout_data = {~data_in[WIDTH], data_in[WIDTH-1:0], 1'b0};out_inv = 1'b0;end// - 2*src_data3'b100:beginout_data = { data_in[WIDTH],~data_in[WIDTH-1:0], 1'b1};out_inv = 1'b1;enddefault:beginout_data = {1'h1,{WIDTH+1{1'h0}}};out_inv = 1'b0;endendcaseendendmodule