基于radix4的booth乘法器设计

下述乘法器是基于radix 4的booth乘法器,常用于集成电路IC的乘法器设计。

  1. 支持位宽可设置
  2. 支持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_a

        assign 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 endgenerate

    assign 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)begin
        prod = 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 @(*) begin
        case(code)
    // +/- 0*src_data
            3'b000,
            3'b111:
            begin
                out_data = {1'h1,{WIDTH+1{1'h0}}};
                out_inv = 1'b0;
            end
    // + 1*src_data
            3'b001,
            3'b010:
            begin
                out_data = {~data_in[WIDTH], data_in};
                out_inv = 1'b0;
            end
    // - 1*src_data
            3'b101,
            3'b110:
            begin
                out_data = { data_in[WIDTH],~data_in};
                out_inv = 1'b1;
            end
    // + 2*src_data
            3'b011:
            begin
                out_data = {~data_in[WIDTH], data_in[WIDTH-1:0], 1'b0};
                out_inv = 1'b0;
            end
    // - 2*src_data
            3'b100:
            begin
                out_data = { data_in[WIDTH],~data_in[WIDTH-1:0], 1'b1};
                out_inv = 1'b1;
            end
            default:
            begin
                out_data = {1'h1,{WIDTH+1{1'h0}}};
                out_inv = 1'b0;
            end
        endcase
    end


endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值