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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpDiv.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
//       ||
//       ||
//
//
//      fpDiv.v
//      fpDiv.v
Line 40... Line 40...
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 92... Line 92...
// The following is a template for a quiet nan. (MSB=1)
// The following is a template for a quiet nan. (MSB=1)
wire [FMSB:0] qNaN  = {1'b1,{FMSB{1'b0}}};
wire [FMSB:0] qNaN  = {1'b1,{FMSB{1'b0}}};
 
 
// variables
// variables
wire [EMSB+2:0] ex1;     // sum of exponents
wire [EMSB+2:0] ex1;     // sum of exponents
wire [FX:0] divo;
wire [(FMSB+9)*2-1:0] divo;
 
 
// Operands
// Operands
wire sa, sb;                    // sign bit
wire sa, sb;                    // sign bit
wire [EMSB:0] xa, xb;    // exponent bits
wire [EMSB:0] xa, xb;    // exponent bits
wire [FMSB+1:0] fracta, fractb;
wire [FMSB+1:0] fracta, fractb;
wire a_dn, b_dn;                        // a/b is denormalized
wire a_dn, b_dn;                        // a/b is denormalized
wire az, bz;
wire az, bz;
wire aInf, bInf;
wire aInf, bInf;
wire aNan,bNan;
wire aNan,bNan;
 
wire done1;
 
wire [7:0] lzcnt;
 
 
// -----------------------------------------------------------
// -----------------------------------------------------------
// - decode the input operands
// - decode the input operands
// - derive basic information
// - derive basic information
// - calculate exponent
// - calculate exponent
Line 117... Line 119...
 
 
// Compute the exponent.
// Compute the exponent.
// - correct the exponent for denormalized operands
// - correct the exponent for denormalized operands
// - adjust the difference by the bias (add 127)
// - adjust the difference by the bias (add 127)
// - also factor in the different decimal position for division
// - also factor in the different decimal position for division
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB - 1;
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB + 9 - lzcnt;
 
 
// check for exponent underflow/overflow
// check for exponent underflow/overflow
wire under = ex1[EMSB+2];       // MSB set = negative exponent
wire under = ex1[EMSB+2];       // MSB set = negative exponent
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
 
 
// Perform divide
// Perform divide
// could take either 1 or 16 clock cycles
// could take either 1 or 16 clock cycles
fpdivr8 #(FMSB+2,2) u2 (.clk(clk), .ld(ld), .a({3'b0,fracta}), .b({3'b0,fractb}), .q(divo), .r(), .done(done));
fpdivr8 #(FMSB+9,2) u2 (.clk(clk), .ld(ld), .a({fracta,7'b0}), .b({fractb,7'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
 
delay1 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done));
 
 
 
 
// determine when a NaN is output
// determine when a NaN is output
wire qNaNOut = (az&bz)|(aInf&bInf);
wire qNaNOut = (az&bz)|(aInf&bInf);
 
wire [(FMSB+9)*2-1:0] divo1 = divo[(FMSB+9)*2-1:0] << (lzcnt-2);
 
 
always @(posedge clk)
always @(posedge clk)
        if (ce) begin
        if (ce) begin
                if (done) begin
                if (done1) begin
                        casex({qNaNOut|aNan|bNan,bInf,bz})
                        casez({qNaNOut|aNan|bNan,bInf,bz,over,under})
                        3'b1xx:         xo = infXp;     // NaN exponent value
                        5'b1????:               xo = infXp;     // NaN exponent value
                        3'bx1x:         xo = 0;          // divide by inf
                        5'b01???:               xo = 0;          // divide by inf
                        3'bxx1:         xo = infXp;     // divide by zero
                        5'b001??:               xo = infXp;     // divide by zero
 
                        5'b0001?:               xo = infXp;     // overflow
 
                        5'b00001:               xo = 0;          // underflow
                        default:        xo = ex1;               // normal or underflow: passthru neg. exp. for normalization
                        default:        xo = ex1;               // normal or underflow: passthru neg. exp. for normalization
                        endcase
                        endcase
 
 
                        casex({aNan,bNan,qNaNOut,bInf,bz})
                        casez({aNan,bNan,qNaNOut,bInf,bz,over})
                        5'b1xxxx:       mo = {1'b0,a[FMSB:0],{FMSB+1{1'b0}}};
                        6'b1?????:      mo = {1'b1,a[FMSB:0],{FMSB+1{1'b0}}};
                        5'bx1xxx:       mo = {1'b0,b[FMSB:0],{FMSB+1{1'b0}}};
                        6'b01????:      mo = {1'b1,b[FMSB:0],{FMSB+1{1'b0}}};
                        5'bxx1xx:               mo = {1'b0,qNaN[FMSB:0]|{aInf,1'b0}|{az,bz},{FMSB+1{1'b0}}};
                        6'b001???:              mo = {1'b1,qNaN[FMSB:0]|{aInf,1'b0}|{az,bz},{FMSB+1{1'b0}}};
                        5'bxxx1x:               mo = 0;  // div by inf
                        6'b0001??:              mo = 0;  // div by inf
                        5'bxxxx1:               mo = 0;  // div by zero
                        6'b00001?:              mo = 0;  // div by zero
                        default:        mo = divo;      // plain div
                        6'b000001:              mo = 0;  // Inf exponent
 
                        default:                mo = divo1[(FMSB+9)*2-1:14];    // plain div
                        endcase
                        endcase
 
 
                        so              = sa ^ sb;
                        so              = sa ^ sb;
                        sign_exe        = sa & sb;
                        sign_exe        = sa & sb;
                        overflow        = over;
                        overflow        = over;
Line 158... Line 166...
                end
                end
        end
        end
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file
 
module fpDivnr(clk, ce, ld, a, b, o, rm, done, 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 ld;
 
input  [MSB:0] a, b;
 
output [MSB:0] o;
 
input [2:0] rm;
 
output sign_exe;
 
output done;
 
output inf;
 
output overflow;
 
output underflow;
 
 
 
wire [EX:0] o1;
 
wire sign_exe1, inf1, overflow1, underflow1;
 
wire [MSB+3:0] fpn0;
 
wire done1;
 
 
 
fpDiv       #(WID) u1 (clk, ce, ld, a, b, o1, done1, sign_exe1, 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));
 
delay2          #(1)   u8(.clk(clk), .ce(ce), .i(done1), .o(done));
 
endmodule
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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