⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boot_mul.v

📁 这是我用verilog hdl语言写的浮点乘法器,用的是基4的booth算法,对于部分积使用了5-2压缩和3-2压缩,欢迎大家指点,也欢迎大家把它改成流水线以提高速度.
💻 V
字号:
module boot_mul(a_i,b_i,clk_i,sign_i,mul_o,sign_b,mul_tree);
parameter length=32;
parameter number=length/2;
input[length-1:0]       a_i;
input[length-1:0]       b_i;
input                   clk_i;
input                   sign_i; //sign_i=0,unsign operation; otherwise, sign operation;
output[2*length-1:0]    mul_o;  
output[63:0]mul_tree;
output[2*length-1:0]    sign_b;   
                     
wire[length:0]           temp_a;
wire                     sign_a;

wire[length+1:0]         temp_b;
//unsigned and signed preprocess

assign temp_a={a_i[length-1]&sign_i,a_i};//use the sign value to extern
assign temp_b={{2{b_i[length-1]&sign_i}},b_i};//use the sign value to extern

//unsigned multiplied result for compare
assign sign_b= a_i*b_i;
wire[number:0]          as,ov,te,sub_valid;


bootcoder inst0 ({temp_b[1:0],1'b0},as[0], ov[0], te[0], sub_valid[0]);
bootcoder inst1 ( temp_b[3:1],   as[1], ov[1], te[1], sub_valid[1]);
bootcoder inst2 ( temp_b[5:3],   as[2], ov[2], te[2], sub_valid[2]);
bootcoder inst3 ( temp_b[7:5],   as[3], ov[3], te[3], sub_valid[3]);
bootcoder inst4 ( temp_b[9:7],   as[4], ov[4], te[4], sub_valid[4]);
bootcoder inst5 ( temp_b[11:9],  as[5], ov[5], te[5], sub_valid[5]);
bootcoder inst6 ( temp_b[13:11], as[6], ov[6], te[6], sub_valid[6]);
bootcoder inst7 ( temp_b[15:13], as[7], ov[7], te[7], sub_valid[7]);
bootcoder inst8 ( temp_b[17:15], as[8], ov[8], te[8], sub_valid[8]);
bootcoder inst9 ( temp_b[19:17], as[9], ov[9], te[9], sub_valid[9]);
bootcoder inst10( temp_b[21:19], as[10],ov[10],te[10],sub_valid[10]);
bootcoder inst11( temp_b[23:21], as[11],ov[11],te[11],sub_valid[11]);
bootcoder inst12( temp_b[25:23], as[12],ov[12],te[12],sub_valid[12]);
bootcoder inst13( temp_b[27:25], as[13],ov[13],te[13],sub_valid[13]);
bootcoder inst14( temp_b[29:27], as[14],ov[14],te[14],sub_valid[14]);
bootcoder inst15( temp_b[31:29], as[15],ov[15],te[15],sub_valid[15]);
bootcoder inst16( temp_b[33:31], as[16],ov[16],te[16],sub_valid[16]);



reg[length+1:0]  temp0 ;
reg[length+3:0]  temp1 ;
reg[length+5:0]  temp2 ;
reg[length+7:0]  temp3 ;           
reg[length+9:0]  temp4 ;
reg[length+11:0] temp5 ;
reg[length+13:0] temp6 ;
reg[length+15:0] temp7 ;  
reg[length+17:0] temp8 ;
reg[length+19:0] temp9 ;
reg[length+21:0] temp10;
reg[length+23:0] temp11;  
reg[length+25:0] temp12;
reg[length+27:0] temp13;
reg[length+29:0] temp14;
reg[length+31:0] temp15;  
reg[length+31:0] temp16;

reg[16:0]        temp17;





//get partial result
always @(temp_a or ov or as or te)
begin
    temp0 <= partient(ov[0], as[0], te[0], temp_a);
    temp1 <= partient(ov[1], as[1], te[1], temp_a)<<2;   
    temp2 <= partient(ov[2], as[2], te[2], temp_a)<<4;   
    temp3 <= partient(ov[3], as[3], te[3], temp_a)<<6;
    temp4 <= partient(ov[4], as[4], te[4], temp_a)<<8;
    temp5 <= partient(ov[5], as[5], te[5], temp_a)<<10;   
    temp6 <= partient(ov[6], as[6], te[6], temp_a)<<12;   
    temp7 <= partient(ov[7], as[7], te[7], temp_a)<<14;
    temp8 <= partient(ov[8], as[8], te[8], temp_a)<<16;
    temp9 <= partient(ov[9], as[9], te[9], temp_a)<<18;   
    temp10<= partient(ov[10],as[10],te[10],temp_a)<<20;   
    temp11<= partient(ov[11],as[11],te[11],temp_a)<<22;
    temp12<= partient(ov[12],as[12],te[12],temp_a)<<24;
    temp13<= partient(ov[13],as[13],te[13],temp_a)<<26;   
    temp14<= partient(ov[14],as[14],te[14],temp_a)<<28;   
    temp15<= partient(ov[15],as[15],te[15],temp_a)<<30;
    temp16<= partient(ov[16],as[16],te[16],temp_a)<<32;//if it is sign operation, the line is lost;if it is unsign, it is a or 0
    temp17<= {   sub_valid[16],
               1'b0,sub_valid[15],
               1'b0,sub_valid[14],  
               1'b0,sub_valid[13],
               1'b0,sub_valid[12],                           
               1'b0,sub_valid[11],
               1'b0,sub_valid[10],
               1'b0,sub_valid[9],
               1'b0,sub_valid[8],
               1'b0,sub_valid[7],
               1'b0,sub_valid[6],
               1'b0,sub_valid[5],
               1'b0,sub_valid[4],
               1'b0,sub_valid[3],
               1'b0,sub_valid[2],
               1'b0,sub_valid[1],
               1'b0,sub_valid[0]};

end                                       
// ********general add to test the result
wire[63:0] sum0;
wire[63:0] sum1;
wire[63:0] sum2;
wire[63:0] sum3;
wire[63:0] sum4;
wire[63:0] sum5;
wire[63:0] sum6;
wire[63:0] sum7;
wire[63:0] add0;
wire[63:0] add1;
wire[63:0] add2;
wire[63:0] add3;
wire[63:0] c0;
wire[63:0] c1;
wire[63:0] c2;
wire[63:0] cout;

assign  sum0 = {{30{temp0[length+1]}},temp0}+{{28{temp1[length+3]}},temp1};
assign  sum1 = {{26{temp2[length+5]}},temp2}+{{24{temp3[length+7]}},temp3};                                      
assign  sum2 = {{22{temp4[length+9]}},temp4}+{{20{temp5[length+11]}},temp5};
assign  sum3 = {{18{temp6[length+13]}},temp6}+{{16{temp7[length+15]}},temp7};
assign  sum4 = {{14{temp8[length+17]}},temp8}+{{12{temp9[length+19]}},temp9};
assign  sum5 = {{10{temp10[length+21]}},temp10}+{{8{temp11[length+23]}},temp11};                                      
assign  sum6 = {{6{temp12[length+25]}},temp12}+{{4{temp13[length+27]}},temp13};
assign  sum7 = {{2{temp14[length+29]}},temp14}+temp15;


assign  add0 =sum0+sum1;
assign  add1 =sum2+sum3;
assign  add2= sum4+sum5;
assign  add3= sum6+sum7;

assign  c0  = add0+add1;
assign  c1  = add2+add3;
assign  c2  = temp16+temp17;

assign  cout= c0+c1;
assign  mul_o= cout+c2;
//***********************************************

//wallace tree
wire[63:0]s_l1_0_o;
wire[63:0]s_l1_1_o;
wire[63:0]s_l1_2_o;
wire[63:0]s_l1_3_o;
wire[63:0]s_l1_4_o;
wire[63:0]s_l1_5_o;


wire[63:0]c_l1_0_o;
wire[63:0]c_l1_1_o;
wire[63:0]c_l1_2_o;
wire[63:0]c_l1_3_o;
wire[63:0]c_l1_4_o;
wire[63:0]c_l1_5_o;


wire[64:0]s_l2_0_o;
wire[64:0]s_l2_1_o;
wire[64:0]s_l2_2_o;

wire[64:0]c_l2_0_o;
wire[64:0]c_l2_1_o;
wire[64:0]c_l2_2_o;

wire[63:0]s_l3_0_o;
wire[63:0]s_l3_1_o;

wire[63:0]c_l3_0_o;
wire[63:0]c_l3_1_o;


wire[64:0]s_l4_o;
wire[64:0]c_l4_o;

wire[63:0]mul_tree;
wire      co_l2_0_o,co_l2_1_o,co_l2_2_o;
wire      co_l4_o;



csa line1_0(.i0_i({{30{temp0[length+1]}},temp0})  ,.i1_i({{28{temp1[length+3]}},temp1})   ,.i2_i({{26{temp2[length+5]}},temp2})  ,.s_o(s_l1_0_o),.c_o(c_l1_0_o));
csa line1_1(.i0_i({{24{temp3[length+7]}},temp3})  ,.i1_i({{22{temp4[length+9]}},temp4})   ,.i2_i({{20{temp5[length+11]}},temp5}) ,.s_o(s_l1_1_o),.c_o(c_l1_1_o));
csa line1_2(.i0_i({{18{temp6[length+13]}},temp6}) ,.i1_i({{16{temp7[length+15]}},temp7})  ,.i2_i({{14{temp8[length+17]}},temp8}) ,.s_o(s_l1_2_o),.c_o(c_l1_2_o));
csa line1_3(.i0_i({{12{temp9[length+19]}},temp9}) ,.i1_i({{10{temp10[length+21]}},temp10}),.i2_i({{8{temp11[length+23]}},temp11}),.s_o(s_l1_3_o),.c_o(c_l1_3_o));
csa line1_4(.i0_i({{6{temp12[length+25]}},temp12}),.i1_i({{4{temp13[length+27]}},temp13}) ,.i2_i({{2{temp14[length+29]}},temp14}),.s_o(s_l1_4_o),.c_o(c_l1_4_o));
csa line1_5(.i0_i(temp15)                         ,.i1_i(temp16)                          ,.i2_i({{47{1'b0}},temp17})            ,.s_o(s_l1_5_o),.c_o(c_l1_5_o));

C42_l line2_0(.i0(s_l1_0_o),.i1(s_l1_1_o),.i2(s_l1_2_o),   .i3(s_l1_3_o),   .ci(1'b0),.d(s_l2_0_o),.c(c_l2_0_o),.co(co_l2_0_o));
C42_l line2_1(.i0(s_l1_4_o),.i1(s_l1_5_o),.i2(c_l1_0_o<<1),.i3(c_l1_1_o<<1),.ci(1'b0),.d(s_l2_1_o),.c(c_l2_1_o),.co(co_l2_1_o));
C42_l line2_2(.i0(c_l1_2_o),.i1(c_l1_3_o),.i2(c_l1_4_o),   .i3(c_l1_5_o),   .ci(1'b0),.d(s_l2_2_o),.c(c_l2_2_o),.co(co_l2_2_o));

csa line3_0(.i0_i(s_l2_0_o[63:0]),.i1_i(s_l2_1_o[63:0]),.i2_i(s_l2_2_o[63:0]<<1),.s_o(s_l3_0_o),.c_o(c_l3_0_o));
csa line3_1(.i0_i(c_l2_0_o[63:0]),.i1_i(c_l2_1_o[63:0]),.i2_i(c_l2_2_o[63:0]<<1),.s_o(s_l3_1_o),.c_o(c_l3_1_o));

C42_l line4_0(.i0(s_l3_0_o),.i1(c_l3_0_o<<1),.i2(s_l3_1_o<<1),.i3(c_l3_1_o<<2),.ci(1'b0),.d(s_l4_o),.c(c_l4_o),.co(co_l4_o));

assign mul_tree=(c_l4_o<<1)+s_l4_o;


function[34:0] partient;
input ov,as,te;
input[32:0] temp_a;
//always @(temp_a or ov or as or te)
begin
//got the partient result  
   if(ov)  //operation a_i;
        begin   
          if(as)     partient={~temp_a[length],~temp_a}; //sub  
          else       partient={temp_a[length],temp_a};  //add
        end 
   else if(te)    //operation 2*a_i
         begin
          if(as)     partient=~(temp_a<<1); //sub
          else       partient=  temp_a<<1; //add
         end
    else
                     partient=0;                  
end
endfunction

endmodule  







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -