OpenCores
URL https://opencores.org/ocsvn/ft816float/ft816float/trunk

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpMul.v] - Diff between revs 8 and 10

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 8 Rev 10
Line 1... Line 1...
`timescale 1ns / 1ps
`timescale 1ns / 1ps
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2006-2016  Robert Finch, Waterloo
//   \\__/ o\    (C) 2006-2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
//      fpMul.v
//      fpMul.v
Line 55... Line 55...
localparam EMSB = WID==128 ? 14 :
localparam EMSB = WID==128 ? 14 :
                  WID==96 ? 14 :
                  WID==96 ? 14 :
                  WID==80 ? 14 :
                  WID==80 ? 14 :
                  WID==64 ? 10 :
                  WID==64 ? 10 :
                                  WID==52 ? 10 :
                                  WID==52 ? 10 :
                                  WID==48 ? 10 :
                                  WID==48 ? 11 :
                                  WID==44 ? 10 :
                                  WID==44 ? 10 :
                                  WID==42 ? 10 :
                                  WID==42 ? 10 :
                                  WID==40 ?  9 :
                                  WID==40 ?  9 :
                                  WID==32 ?  7 :
                                  WID==32 ?  7 :
                                  WID==24 ?  6 : 4;
                                  WID==24 ?  6 : 4;
localparam FMSB = WID==128 ? 111 :
localparam FMSB = WID==128 ? 111 :
                  WID==96 ? 79 :
                  WID==96 ? 79 :
                  WID==80 ? 63 :
                  WID==80 ? 63 :
                  WID==64 ? 51 :
                  WID==64 ? 51 :
                                  WID==52 ? 39 :
                                  WID==52 ? 39 :
                                  WID==48 ? 35 :
                                  WID==48 ? 34 :
                                  WID==44 ? 31 :
                                  WID==44 ? 31 :
                                  WID==42 ? 29 :
                                  WID==42 ? 29 :
                                  WID==40 ? 28 :
                                  WID==40 ? 28 :
                                  WID==32 ? 22 :
                                  WID==32 ? 22 :
                                  WID==24 ? 15 : 9;
                                  WID==24 ? 15 : 9;
Line 129... Line 129...
// correct the exponent for denormalized operands
// correct the exponent for denormalized operands
// adjust the sum by the exponent offset (subtract 127)
// adjust the sum by the exponent offset (subtract 127)
// mul: ex1 = xa + xb,  result should always be < 1ffh
// mul: ex1 = xa + xb,  result should always be < 1ffh
assign ex1 = (az|bz) ? 0 : (xa|a_dn) + (xb|b_dn) - bias;
assign ex1 = (az|bz) ? 0 : (xa|a_dn) + (xb|b_dn) - bias;
 
 
 
generate
 
if (WID==64) begin
reg [35:0] p00,p01,p02;
reg [35:0] p00,p01,p02;
reg [35:0] p10,p11,p12;
reg [35:0] p10,p11,p12;
reg [35:0] p20,p21,p22;
reg [35:0] p20,p21,p22;
generate
 
if (WID==64) begin
 
        always @(posedge clk)
        always @(posedge clk)
        if (ce) begin
        if (ce) begin
                p00 <= fracta[17: 0] * fractb[17: 0];
                p00 <= fracta[17: 0] * fractb[17: 0];
                p01 <= fracta[35:18] * fractb[17: 0];
                p01 <= fracta[35:18] * fractb[17: 0];
                p02 <= fracta[52:36] * fractb[17: 0];
                p02 <= fracta[52:36] * fractb[17: 0];
Line 152... Line 152...
                                        {p22,72'b0} + {p21,54'b0} + {p20,36'b0}
                                        {p22,72'b0} + {p21,54'b0} + {p20,36'b0}
                                ;
                                ;
        end
        end
end
end
else if (WID==32) begin
else if (WID==32) begin
 
reg [23:0] p00,p01,p02;
 
reg [23:0] p10,p11,p12;
 
reg [23:0] p20,p21,p22;
        always @(posedge clk)
        always @(posedge clk)
        if (ce) begin
        if (ce) begin
                p00 <= fracta[17: 0] * fractb[17: 0];
                p00 <= fracta[11: 0] * fractb[11: 0];
                p01 <= fracta[23:18] * fractb[17: 0];
                p01 <= fracta[23:12] * fractb[11: 0];
                p10 <= fracta[17: 0] * fractb[23:18];
                p10 <= fracta[11: 0] * fractb[23:12];
                p11 <= fracta[23:18] * fractb[23:18];
                p11 <= fracta[23:12] * fractb[23:12];
                fract1 <= {p11,p00} + {p01,18'b0} + {p10,18'b0};
                fract1 <= {p11,p00} + {p01,12'b0} + {p10,12'b0};
        end
        end
end
end
else begin
else begin
 
reg [35:0] p00,p01,p02;
 
reg [35:0] p10,p11,p12;
 
reg [35:0] p20,p21,p22;
        always @(posedge clk)
        always @(posedge clk)
    if (ce)
    if (ce) begin
        fract1 <= fracta * fractb;
        fract1a <= fracta * fractb;
 
        fract1 <= fract1a;
 
    end
end
end
endgenerate
endgenerate
 
 
// Status
// Status
wire under1, over1;
wire under1, over1;
wire under = ex1[EMSB+2];       // exponent underflow
wire under = ex1[EMSB+2];       // exponent underflow
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
 
 
delay2 #(EMSB+1) u3 (.clk(clk), .ce(ce), .i(ex1[EMSB:0]), .o(ex2) );
delay2 #(EMSB+1) u3 (.clk(clk), .ce(ce), .i(ex1[EMSB:0]), .o(ex2) );
delay2 #(FX+1) u4 (.clk(clk), .ce(ce), .i(fract1), .o(fracto) );
 
delay2 u2a (.clk(clk), .ce(ce), .i(aInf), .o(aInf1) );
delay2 u2a (.clk(clk), .ce(ce), .i(aInf), .o(aInf1) );
delay2 u2b (.clk(clk), .ce(ce), .i(bInf), .o(bInf1) );
delay2 u2b (.clk(clk), .ce(ce), .i(bInf), .o(bInf1) );
delay2 u6  (.clk(clk), .ce(ce), .i(under), .o(under1) );
delay2 u6  (.clk(clk), .ce(ce), .i(under), .o(under1) );
delay2 u7  (.clk(clk), .ce(ce), .i(over), .o(over1) );
delay2 u7  (.clk(clk), .ce(ce), .i(over), .o(over1) );
 
 
Line 199... Line 206...
wire so1;
wire so1;
delay3 u8 (.clk(clk), .ce(ce), .i(sa ^ sb), .o(so1) );// two clock delay!
delay3 u8 (.clk(clk), .ce(ce), .i(sa ^ sb), .o(so1) );// two clock delay!
 
 
always @(posedge clk)
always @(posedge clk)
        if (ce)
        if (ce)
                casex({qNaNOut|aNan1|bNan1,aInf1,bInf1,over1,under1})
                casez({qNaNOut|aNan1|bNan1,aInf1,bInf1,over1,under1})
                5'b1xxxx:       xo1 = infXp;    // qNaN - infinity * zero
                5'b1????:       xo1 = infXp;    // qNaN - infinity * zero
                5'b01xxx:       xo1 = infXp;    // 'a' infinite
                5'b01???:       xo1 = infXp;    // 'a' infinite
                5'b001xx:       xo1 = infXp;    // 'b' infinite
                5'b001??:       xo1 = infXp;    // 'b' infinite
                5'b0001x:       xo1 = infXp;    // result overflow
                5'b0001?:       xo1 = infXp;    // result overflow
                5'b00001:       xo1 = 0;         // underflow
                5'b00001:       xo1 = ex2[EMSB:0];//0;           // underflow
                default:        xo1 = ex2[EMSB:0];       // situation normal
                default:        xo1 = ex2[EMSB:0];       // situation normal
                endcase
                endcase
 
 
always @(posedge clk)
always @(posedge clk)
        if (ce)
        if (ce)
                casex({aNan1,bNan1,qNaNOut,aInf1,bInf1,over1})
                casez({aNan1,bNan1,qNaNOut,aInf1,bInf1,over1})
                6'b1xxxxx:  mo1 = {1'b0,a1[FMSB:0],{FMSB+1{1'b0}}};
                6'b1?????:  mo1 = {1'b0,a1[FMSB:0],{FMSB+1{1'b0}}};
        6'bx1xxxx:  mo1 = {1'b0,b1[FMSB:0],{FMSB+1{1'b0}}};
        6'b01????:  mo1 = {1'b0,b1[FMSB:0],{FMSB+1{1'b0}}};
                6'bxx1xxx:      mo1 = {1'b0,qNaN|3'd4,{FMSB+1{1'b0}}};  // multiply inf * zero
                6'b001???:      mo1 = {1'b0,qNaN|3'd4,{FMSB+1{1'b0}}};  // multiply inf * zero
                6'b0001xx:      mo1 = 0; // mul inf's
                6'b0001??:      mo1 = 0; // mul inf's
                6'b00001x:      mo1 = 0; // mul inf's
                6'b00001?:      mo1 = 0; // mul inf's
                6'b000001:      mo1 = 0; // mul overflow
                6'b000001:      mo1 = 0; // mul overflow
                default:        mo1 = fracto;
                default:        mo1 = fract1;
                endcase
                endcase
 
 
delay3 u10 (.clk(clk), .ce(ce), .i(sa & sb), .o(sign_exe) );
delay3 u10 (.clk(clk), .ce(ce), .i(sa & sb), .o(sign_exe) );
delay1 u11 (.clk(clk), .ce(ce), .i(over1),  .o(overflow) );
delay1 u11 (.clk(clk), .ce(ce), .i(over1),  .o(overflow) );
delay1 u12 (.clk(clk), .ce(ce), .i(over1),  .o(inf) );
delay1 u12 (.clk(clk), .ce(ce), .i(over1),  .o(inf) );
Line 229... Line 236...
 
 
assign o = {so1,xo1,mo1};
assign o = {so1,xo1,mo1};
 
 
endmodule
endmodule
 
 
 
module fpMulnr(clk, ce, a, b, o, rm, sign_exe, inf, overflow, underflow);
 
parameter WID=32;
 
localparam MSB = WID-1;
 
localparam EMSB = WID==128 ? 14 :
 
                  WID==96 ? 14 :
 
                  WID==80 ? 14 :
 
                  WID==64 ? 10 :
 
                                  WID==52 ? 10 :
 
                                  WID==48 ? 11 :
 
                                  WID==44 ? 10 :
 
                                  WID==42 ? 10 :
 
                                  WID==40 ?  9 :
 
                                  WID==32 ?  7 :
 
                                  WID==24 ?  6 : 4;
 
localparam FMSB = WID==128 ? 111 :
 
                  WID==96 ? 79 :
 
                  WID==80 ? 63 :
 
                  WID==64 ? 51 :
 
                                  WID==52 ? 39 :
 
                                  WID==48 ? 34 :
 
                                  WID==44 ? 31 :
 
                                  WID==42 ? 29 :
 
                                  WID==40 ? 28 :
 
                                  WID==32 ? 22 :
 
                                  WID==24 ? 15 : 9;
 
 
 
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
 
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
 
input clk;
 
input ce;
 
input  [MSB:0] a, b;
 
output [MSB:0] o;
 
input [2:0] rm;
 
output sign_exe;
 
output inf;
 
output overflow;
 
output underflow;
 
 
 
wire [EX:0] o1;
 
wire sign_exe1, inf1, overflow1, underflow1;
 
wire [MSB+3:0] fpn0;
 
 
 
fpMul       #(WID) u1 (clk, ce, a, b, o1, sign_exe1, inf1, overflow1, underflow1);
 
fpNormalize #(WID) u2(.clk(clk), .ce(ce), .under(underflow1), .i(o1), .o(fpn0) );
 
fpRoundReg  #(WID) u3(.clk(clk), .ce(ce), .rm(rm), .i(fpn0), .o(o) );
 
delay2      #(1)   u4(.clk(clk), .ce(ce), .i(sign_exe1), .o(sign_exe));
 
delay2      #(1)   u5(.clk(clk), .ce(ce), .i(inf1), .o(inf));
 
delay2      #(1)   u6(.clk(clk), .ce(ce), .i(overflow1), .o(overflow));
 
delay2      #(1)   u7(.clk(clk), .ce(ce), .i(underflow1), .o(underflow));
 
endmodule
 
 
module fpMul_tb();
module fpMul_tb();
reg clk;
reg clk;
 
 
initial begin
initial begin
        clk = 0;
        clk = 0;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.