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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpUnit.v] - Diff between revs 10 and 26

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

Rev 10 Rev 26
Line 1... Line 1...
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2006-2018  Robert Finch, Waterloo
//   \\__/ o\    (C) 2006-2019  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
Line 17... Line 17...
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//
//
//
//
// DSD
 
//      fpUnit.v
//      fpUnit.v
//  - floating point unit
//  - floating point unit
//  - parameterized width
//  - parameterized width
//  - IEEE 754 representation
//  - IEEE 754 representation
//
//
//      NaN Value               Origin
//      NaN Value               Origin
// 31'h7FC00001    - infinity - infinity
// 31'h7FC00001    - infinity - infinity
// 31'h7FC00002    - infinity / infinity
// 31'h7FC00002    - infinity / infinity
// 31'h7FC00003    - zero / zero
// 31'h7FC00003    - zero / zero
// 31'h7FC00004    - infinity X zero
// 31'h7FC00004    - infinity X zero
 
// 31'h7FC00005    - square root of infinity
 
// 31'h7FC00006          - square root of negative number
//
//
// Whenever the fpu encounters a NaN input, the NaN is
// Whenever the fpu encounters a NaN input, the NaN is
// passed through to the output.
// passed through to the output.
//
//
// Ref: Webpack 8.2  Spartan3-4  xc3s1000-4ft256
// Ref: Webpack 8.2  Spartan3-4  xc3s1000-4ft256
Line 80... Line 81...
`define VFNEG       6'h16
`define VFNEG       6'h16
`define VFTOI       6'h24
`define VFTOI       6'h24
`define VITOF       6'h25
`define VITOF       6'h25
`define VFMUL       6'h3A
`define VFMUL       6'h3A
`define VFDIV       6'h3E
`define VFDIV       6'h3E
`define FLOAT   6'h0B
`define FLOAT   6'h0F
`define FMOV    6'h10
`define FLT1            4'h1
`define FTOI    6'h12
`define FLT2            4'h2
`define ITOF    6'h13
`define FLT3            4'h3
`define FNEG    6'h14
`define FLT1A           4'h5
`define FABS    6'h15
`define FLT2LI  4'hA
`define FSIGN   6'h16
`define FMA                     5'h00
`define FMAN    6'h17
`define FMS                     5'h01
`define FNABS   6'h18
`define FNMA            5'h02
`define FCVTSD  6'h19
`define FNMS            5'h03
`define FCVTSQ  6'h1B
`define FMOV    5'h00
`define FSTAT   6'h1C
`define FTOI    5'h02
`define FTX     6'h20
`define ITOF    5'h03
`define FCX     6'h21
`define FNEG    5'h04
`define FEX     6'h22
`define FABS    5'h05
`define FDX     6'h23
`define FSIGN   5'h06
`define FRM     6'h24
`define FMAN    5'h07
`define FCVTDS  6'h29
`define FNABS   5'h08
 
`define FCVTSD  5'h09
`define FADD    6'h04
//`define FCVTSQ  6'h1B
`define FSUB    6'h05
`define FSTAT   5'h0C
`define FCMP    6'h06
`define FSQRT           5'h0D
`define FMUL    6'h08
`define FTX     5'h10
`define FDIV    6'h09
`define FCX     5'h11
 
`define FEX     5'h12
`define QINFOS          23'h7FC000              // info
`define FDX     5'h13
`define QSUBINFS        31'h7FC00001    // - infinity - infinity
`define FRM     5'h14
`define QINFDIVS        31'h7FC00002    // - infinity / infinity
`define TRUNC           5'h15
`define QZEROZEROS      31'h7FC00003    // - zero / zero
`define FCVTDS  5'h19
`define QINFZEROS       31'h7FC00004    // - infinity X zero
 
 
`define FSCALEB 5'h00
`define QINFOD          52'hFF80000000000               // info
`define FADD    5'h04
`define QSUBINFD        63'h7FF0000000000001    // - infinity - infinity
`define FSUB    5'h05
`define QINFDIVD        63'h7FF0000000000002    // - infinity / infinity
`define FCMP    5'h06
`define QZEROZEROD  63'h7FF0000000000003        // - zero / zero
`define FMUL    5'h08
`define QINFZEROD       63'h7FF0000000000004    // - infinity X zero
`define FDIV    5'h09
 
`define FREM            5'h0A
`define QINFODX         64'hFF800000_00000000           // info
`define NXTAFT  5'h0B
`define QSUBINFDX       79'h7FFF000000_0000000001       // - infinity - infinity
// FLT1A
`define QINFDIVDX       79'h7FFF000000_0000000002       // - infinity / infinity
`define FRES            5'h00
`define QZEROZERODX 79'h7FFF000000_0000000003   // - zero / zero
 
`define QINFZERODX      79'h7FFF000000_0000000004       // - infinity X zero
 
 
 
`define QINFOQ          112'hFF800000_0000000000_0000000000             // info
 
`define QSUBINFQ        127'h7F_FF00000000_0000000000_0000000001        // - infinity - infinity
 
`define QINFDIVQ        127'h7F_FF00000000_0000000000_0000000002        // - infinity / infinity
 
`define QZEROZEROQ  127'h7F_FF00000000_0000000000_0000000003    // - zero / zero
 
`define QINFZEROQ       127'h7F_FF00000000_0000000000_0000000004        // - infinity X zero
 
 
 
module fpUnit(rst, clk, ce, ir, ld, a, b, imm, o, csr_i, status, exception, done, rm
`include "fp_defines.v"
);
 
 
 
 
module fpUnit(rst, clk, clk4x, ce, ir, ld, a, b, c, imm, o, csr_i, status, exception, done, rm
 
);
parameter WID = 64;
parameter WID = 64;
localparam MSB = WID-1;
`include "fpSize.sv"
localparam EMSB = WID==128 ? 14 :
 
                  WID==96 ? 14 :
 
                  WID==80 ? 14 :
 
                  WID==64 ? 10 :
 
                                  WID==52 ? 10 :
 
                                  WID==48 ? 10 :
 
                                  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 ? 35 :
 
                                  WID==44 ? 31 :
 
                                  WID==42 ? 29 :
 
                                  WID==40 ? 28 :
 
                                  WID==32 ? 22 :
 
                                  WID==24 ? 15 : 9;
 
localparam EMSBS = 7;
localparam EMSBS = 7;
localparam FMSBS = 22;
localparam FMSBS = 22;
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
 
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
 
localparam FXS = (FMSBS+2)*2-1; // the MSB of the expanded fraction
localparam FXS = (FMSBS+2)*2-1; // the MSB of the expanded fraction
localparam EXS = FXS + 1 + EMSBS + 1 + 1 - 1;
localparam EXS = FXS + 1 + EMSBS + 1 + 1 - 1;
 
 
input rst;
input rst;
input clk;
input clk;
 
input clk4x;
input ce;
input ce;
input [31:0] ir;
input [39:0] ir;
input ld;
input ld;
input [MSB:0] a;
input [MSB:0] a;
input [MSB:0] b;
input [MSB:0] b;
 
input [MSB:0] c;
input [5:0] imm;
input [5:0] imm;
output tri [MSB:0] o;
output tri [MSB:0] o;
input [31:0] csr_i;
input [31:0] csr_i;
output [31:0] status;
output [31:0] status;
output exception;
output exception;
output done;
output done;
input [2:0] rm;
input [2:0] rm;
 
 
reg [7:0] fpcnt;
reg [7:0] fpcnt;
assign done = fpcnt==8'h00;
wire rem_done;
 
wire rem_ld;
 
wire op_done = fpcnt==8'h00;
 
assign done = op_done & rem_done;
 
 
//------------------------------------------------------------
//------------------------------------------------------------
// constants
// constants
wire infXpq = {15{1'b1}};
wire infXpq = {15{1'b1}};
wire infXp = {11{1'b1}};        // value for infinite exponent / nan
wire infXp = {11{1'b1}};        // value for infinite exponent / nan
Line 198... Line 173...
wire nso;
wire nso;
wire nsos;
wire nsos;
wire isNan,isNans;
wire isNan,isNans;
wire nanx,nanxs;
wire nanx,nanxs;
 
 
// Decode fp operation
wire latch_res;
 
wire [3:0] op4_r;
 
wire [5:0] func6b_r;
 
wire [2:0] srca;
 
wire [2:0] srcb;
 
wire [3:0] op4_i = ir[9:6];
wire [5:0] op = ir[5:0];
wire [5:0] op = ir[5:0];
wire [5:0] func6b = ir[31:26];
wire [4:0] func6b_i = ir[39:35];
wire [1:0] prec = ir[25:24];
wire fprem = {op4_i,func6b_i} == {`FLT2,`FREM};
 
wire [3:0] op4 = fprem ? op4_r : op4_i;
 
wire [5:0] func6b = fprem ? func6b_r : func6b_i;
 
wire [2:0] insn_rm = ir[30:28];
 
reg [WID-1:0] res;
 
reg [WID-1:0] aop, bop;
 
always @*
 
case(srca)
 
`RES:   aop <= res;
 
default:        aop <= a;
 
endcase
 
always @*
 
case(srcb)
 
`RES:                   bop <= res;
 
`POINT5:
 
case(WID)
 
32:     bop <= `POINT5S;
 
40:     bop <= `POINT5SX;
 
64:     bop <= `POINT5D;
 
80:     bop <= `POINT5DX;
 
endcase
 
default:        bop <= b;
 
endcase
 
 
wire fstat      = {op,func6b} == {`FLOAT,`FSTAT};       // get status
wire [2:0] prec = 3'd4;//ir[25:24];
wire fdiv       = {op,func6b} == {`FLOAT,`FDIV};
 
wire ftx        = {op,func6b} == {`FLOAT,`FTX};         // trigger exception
 
wire fcx        = {op,func6b} == {`FLOAT,`FCX};         // clear exception
 
wire fex        = {op,func6b} == {`FLOAT,`FEX};         // enable exception
 
wire fdx        = {op,func6b} == {`FLOAT,`FDX};         // disable exception
 
wire fcmp       = {op,func6b} == {`FLOAT,`FCMP};
 
wire frm        = {op,func6b} == {`FLOAT,`FRM};  // set rounding mode
 
 
 
wire zl_op =  (op==`FLOAT && (
wire fstat      = {op4,func6b} == {`FLT1,`FSTAT};       // get status
                    (func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN || func6b==`FCVTSQ)) ||
wire fdiv       = {op4,func6b} == {`FLT2,`FDIV};
 
wire ftx        = {op4,func6b} == {`FLT1,`FTX};         // trigger exception
 
wire fcx        = {op4,func6b} == {`FLT1,`FCX};         // clear exception
 
wire fex        = {op4,func6b} == {`FLT1,`FEX};         // enable exception
 
wire fdx        = {op4,func6b} == {`FLT1,`FDX};         // disable exception
 
wire fcmp       = {op4,func6b} == {`FLT2,`FCMP};
 
wire frm        = {op4,func6b} == {`FLT1,`FRM};  // set rounding mode
 
 
 
wire zl_op =  (op4==`FLT1 && (
 
                    (func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN)) ||
                    func6b==`FCMP);
                    func6b==`FCMP);
wire loo_op = (op==`FLOAT && (func6b==`ITOF || func6b==`FTOI));
wire loo_op = (op4==`FLT1 && (func6b==`ITOF || func6b==`FTOI));
wire loo_done;
wire loo_done;
 
 
wire subinf;
wire subinf;
wire zerozero;
wire zerozero;
wire infzero;
wire infzero;
Line 285... Line 289...
reg zerozerox;  // division of zero by zero
reg zerozerox;  // division of zero by zero
reg infdivx;    // division of infinities
reg infdivx;    // division of infinities
reg subinfx;    // subtraction of infinities
reg subinfx;    // subtraction of infinities
reg snanx;              // signalling nan
reg snanx;              // signalling nan
 
 
 
wire fdivs = 1'b0;
wire divDone;
wire divDone;
wire pipe_ce = ce;// & divDone; // divide must be done in order for pipe to clock
wire pipe_ce = ce;// & divDone; // divide must be done in order for pipe to clock
wire precmatch = WID==32 ? ir[28:27]==2'b00 :
wire precmatch = 1'b0;//WID==32 ? ir[28:27]==2'b00 :
                 WID==64 ? ir[28:27]==2'b01 : 1;
                 //WID==64 ? ir[28:27]==2'b01 : 1;
                 /*
                 /*
                 WID==80 ? ir[28:27]==2'b10 :
                 WID==80 ? ir[28:27]==2'b10 :
                 ir[28:27]==2'b11;
                 ir[28:27]==2'b11;
                 */
                 */
always @(posedge clk)
always @(posedge clk)
Line 357... Line 362...
 
 
wire aInf, bInf, aInfs, bInfs;
wire aInf, bInf, aInfs, bInfs;
wire aNan, bNan, aNans, bNans;
wire aNan, bNan, aNans, bNans;
wire az, bz, azs, bzs;
wire az, bz, azs, bzs;
wire [2:0] rmd4; // 1st stage delayed
wire [2:0] rmd4; // 1st stage delayed
wire [5:0] op1, op2;
wire [3:0] op2;
 
wire [5:0] op1;
wire [5:0] fn2;
wire [5:0] fn2;
 
 
wire [MSB:0] zld_o,lood_o;
wire [MSB:0] zld_o,lood_o;
wire [31:0] zls_o,loos_o;
wire [31:0] zls_o,loos_o;
wire [WID-1:0] zlq_o, looq_o;
wire [WID-1:0] zlq_o, looq_o;
fpZLUnit #(WID) u6 (.ir(ir), .a(a), .b(b), .o(zlq_o), .nanx(nanx) );
wire [WID-1:0] scaleb_o;
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .ir(ir), .a(a), .o(looq_o), .done() );
fpZLUnit #(WID) u6 (.ir(ir), .op4(op4), .func5(func6b), .a(aop), .b(bop), .c(c), .o(zlq_o), .nanx(nanx) );
 
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .op4(op4), .func5(func6b), .rm(insn_rm==3'b111 ? rm : insn_rm), .a(aop), .b(bop), .o(looq_o), .done() );
 
fpScaleb u16 (.clk(clk), .ce(pipe_ce), .a(aop), .b(bop), .o(scaleb_o));
 
 
//fpLOOUnit #(32) u7s (.clk(clk), .ce(pipe_ce), .rm(rm), .op(op), .fn(fn), .a(a[31:0]), .o(loos_o), .done() );
//fpLOOUnit #(32) u7s (.clk(clk), .ce(pipe_ce), .rm(rm), .op(op), .fn(fn), .a(a[31:0]), .o(loos_o), .done() );
 
 
fp_decomp #(WID) u1 (.i(a), .sgn(sa), .man(ma), .vz(az), .inf(aInf), .nan(aNan) );
fp_decomp #(WID) u1 (.i(aop), .sgn(sa), .man(ma), .vz(az), .inf(aInf), .nan(aNan) );
fp_decomp #(WID) u2 (.i(b), .sgn(sb), .man(mb), .vz(bz), .inf(bInf), .nan(bNan) );
fp_decomp #(WID) u2 (.i(bop), .sgn(sb), .man(mb), .vz(bz), .inf(bInf), .nan(bNan) );
//fp_decomp #(32) u1s (.i(a[31:0]), .sgn(sas), .man(mas), .vz(azs), .inf(aInfs), .nan(aNans) );
//fp_decomp #(32) u1s (.i(a[31:0]), .sgn(sas), .man(mas), .vz(azs), .inf(aInfs), .nan(aNans) );
//fp_decomp #(32) u2s (.i(b[31:0]), .sgn(sbs), .man(mbs), .vz(bzs), .inf(bInfs), .nan(bNans) );
//fp_decomp #(32) u2s (.i(b[31:0]), .sgn(sbs), .man(mbs), .vz(bzs), .inf(bInfs), .nan(bNans) );
 
 
wire [2:0] rmd = ir[26:24]==3'b111 ? rm : ir[26:24];
wire [2:0] rmd = ir[30:28]==3'b111 ? rm : ir[30:28];
delay4 #(3) u3 (.clk(clk), .ce(pipe_ce), .i(rmd), .o(rmd4) );
delay4 #(3) u3 (.clk(clk), .ce(pipe_ce), .i(rmd), .o(rmd4) );
delay1 #(6) u4 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op1) );
delay1 #(6) u4 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op1) );
delay2 #(6) u5 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op2) );
delay2 #(4) u5 (.clk(clk), .ce(pipe_ce), .i(op4), .o(op2) );
delay2 #(6) u5b (.clk(clk), .ce(pipe_ce), .i(func6b), .o(fn2) );
delay2 #(6) u5b (.clk(clk), .ce(pipe_ce), .i(func6b), .o(fn2) );
 
 
delay5 delay5_3(.clk(clk), .ce(pipe_ce), .i((bz & !aNan & fdiv)|(bzs & !aNans & fdivs)), .o(divByZero) );
delay5 delay5_3(.clk(clk), .ce(pipe_ce), .i((bz & !aNan & fdiv)|(bzs & !aNans & fdivs)), .o(divByZero) );
 
 
// Compute NaN output sign
// Compute NaN output sign
Line 403... Line 412...
wire [MSB:0] fpu_o;
wire [MSB:0] fpu_o;
wire [MSB+3:0] fpn_o;
wire [MSB+3:0] fpn_o;
wire [EX:0] fdiv_o;
wire [EX:0] fdiv_o;
wire [EX:0] fmul_o;
wire [EX:0] fmul_o;
wire [EX:0] fas_o;
wire [EX:0] fas_o;
 
wire [EX:0] fsqrt_o;
reg  [EX:0] fres;
reg  [EX:0] fres;
wire [31:0] fpus_o;
wire [31:0] fpus_o;
wire [31+3:0] fpns_o;
wire [31+3:0] fpns_o;
wire [EXS:0] fdivs_o;
wire [EXS:0] fdivs_o;
wire [EXS:0] fmuls_o;
wire [EXS:0] fmuls_o;
wire [EXS:0] fass_o;
wire [EXS:0] fass_o;
 
wire [EXS:0] fres_o;
reg  [EXS:0] fress;
reg  [EXS:0] fress;
wire divUnder,divUnders;
wire divUnder,divUnders;
wire mulUnder,mulUnders;
wire mulUnder,mulUnders;
reg under,unders;
reg under,unders;
 
wire sqrneg;
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func6b[0]), .a(a), .b(b), .o(fas_o) );
wire fms = func6b==`FMS || func6b==`FNMS;
fpDiv    #(WID) u11(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a), .b(b), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
wire nma = func6b==`FNMA || func6b==`FNMS;
fpMul    #(WID) u12(.clk(clk), .ce(pipe_ce),          .a(a), .b(b), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
wire [WID-1:0] ma_aop = aop ^ (nma << WID-1);
 
 
 
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func6b[0]), .a(aop), .b(bop), .o(fas_o) );
 
fpDiv    #(WID) u11(.clk(clk), .clk4x(clk4x), .ce(pipe_ce), .ld(ld|rem_ld), .a(aop), .b(bop), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
 
fpMul    #(WID) u12(.clk(clk), .ce(pipe_ce),          .a(aop), .b(bop), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
 
fpSqrt   #(WID) u13(.rst(rst), .clk(clk4x), .ce(pipe_ce), .ld(ld), .a(aop), .o(fsqrt_o), .done(), .sqrinf(), .sqrneg(sqrneg) );
 
fpRes    #(WID) u14(.clk(clk), .ce(pipe_ce), .a(aop), .o(fres_o));
 
fpFMA    #(WID) u15(.clk(clk), .ce(pipe_ce), .op(fms), .rm(rmd), .a(ma_aop), .b(bop), .c(c), .o(fma_o), .inf());
 
 
 
fpRemainder ufpr1
 
(
 
        .rst(rst),
 
        .clk(clk),
 
        .ce(ce),
 
        .ld_i(ld),
 
        .ld_o(rem_ld),
 
        .op4_i(op4_i),
 
        .funct6b_i(func6b_i),
 
        .op4_o(op4_r),
 
        .funct6b_o(func6b_r),
 
        .op_done(op_done),
 
        .rem_done(rem_done),
 
        .srca(srca),
 
        .srcb(srcb),
 
        .latch_res(latch_res)
 
);
/*
/*
fpAddsub #(32) u10s(.clk(clk), .ce(pipe_ce), .rm(rm), .op(op[0]), .a(a[31:0]), .b(b[31:0]), .o(fass_o) );
fpAddsub #(32) u10s(.clk(clk), .ce(pipe_ce), .rm(rm), .op(op[0]), .a(a[31:0]), .b(b[31:0]), .o(fass_o) );
fpDiv    #(32) u11s(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a[31:0]), .b(b[31:0]), .o(fdivs_o), .sign_exe(), .underflow(divUnders), .done() );
fpDiv    #(32) u11s(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a[31:0]), .b(b[31:0]), .o(fdivs_o), .sign_exe(), .underflow(divUnders), .done() );
fpMul    #(32) u12s(.clk(clk), .ce(pipe_ce),          .a(a[31:0]), .b(b[31:0]), .o(fmuls_o), .sign_exe(), .inf(), .underflow(mulUnders) );
fpMul    #(32) u12s(.clk(clk), .ce(pipe_ce),          .a(a[31:0]), .b(b[31:0]), .o(fmuls_o), .sign_exe(), .inf(), .underflow(mulUnders) );
*/
*/
always @*
always @*
case(op2)
case(op2)
`FLOAT:
`FLT2,`FLT2LI:
    case (fn2)
    case (fn2)
    `FMUL:      under = mulUnder;
    `FMUL:      under = mulUnder;
    `FDIV:      under = divUnder;
    `FDIV:      under = divUnder;
    default: begin under = 0; unders = 0; end
    default: begin under = 0; unders = 0; end
        endcase
        endcase
`VECTOR:
 
    case (fn2)
 
    `VFMUL:    under = mulUnder;
 
    `VFDIV:    under = divUnder;
 
    default: begin under = 0; unders = 0; end
 
    endcase
 
default: begin under = 0; unders = 0; end
default: begin under = 0; unders = 0; end
endcase
endcase
 
 
always @*
always @*
case(op2)
case(op2)
`FLOAT:
`FLT3:
 
        case(fn2)
 
        `FMA:           fres <= fma_o;
 
        `FMS:           fres <= fma_o;
 
        `FNMA:  fres <= fma_o;
 
        `FNMS:  fres <= fma_o;
 
        default:        fres <= fma_o;
 
        endcase
 
`FLT2,`FLT2LI:
    case(fn2)
    case(fn2)
    `FADD:      fres <= fas_o;
    `FADD:      fres <= fas_o;
    `FSUB:      fres <= fas_o;
    `FSUB:      fres <= fas_o;
    `FMUL:      fres <= fmul_o;
    `FMUL:      fres <= fmul_o;
    `FDIV:      fres <= fdiv_o;
    `FDIV:      fres <= fdiv_o;
 
  `FSCALEB:     fres <= scaleb_o;
    default:    begin fres <= fas_o; fress <= fass_o; end
    default:    begin fres <= fas_o; fress <= fass_o; end
    endcase
    endcase
`VECTOR:
`FLT1:
    case(fn2)
    case(fn2)
    `VFADD:   fres <= fas_o;
  `FSQRT:       fres <= fsqrt_o;
    `VFSUB:   fres <= fas_o;
  default:      begin fres <= 1'd0; fress <= 1'd0; end
    `VFMUL:   fres <= fmul_o;
  endcase
    `VFDIV:   fres <= fdiv_o;
`FLT1A:
    default:    begin fres <= fas_o; fress <= fass_o; end
        case(fn2)
 
        `FRES:  fres <= fres_o;
 
        default:        begin fres <= 1'd0; fress <= 1'd0; end
    endcase
    endcase
default:    begin fres <= fas_o; fress <= fass_o; end
default:    begin fres <= fas_o; fress <= fass_o; end
endcase
endcase
 
 
// pipeline stage
// pipeline stage
Line 501... Line 542...
        giopx,
        giopx,
        gx,
        gx,
        sx,
        sx,
 
 
        1'b0,  // cvtx
        1'b0,  // cvtx
        1'b0,  // sqrtx
        sqrneg, // sqrtx
        fcmp & nanx,
        fcmp & nanx,
        infzero,
        infzero,
        zerozero,
        zerozero,
        infdiv,
        infdiv,
        subinf,
        subinf,
        isNan
        isNan
        };
        };
 
 
assign o = (!fstat) ?
wire [WID-1:0] o1 =
    (frm|fcx|fdx|fex) ? (a|imm) :
    (frm|fcx|fdx|fex) ? (a|imm) :
    zl_op ? zlq_o :
    zl_op ? zlq_o :
    loo_op ? looq_o :
    loo_op ? looq_o :
    {so,fpu_o[MSB-1:0]} : 'bz;
    {so,fpu_o[MSB-1:0]};
assign zero = fpu_o[MSB-1:0]==0;
assign zero = fpu_o[MSB-1:0]==0;
 
assign o = fprem ? res : o1;
 
always @(posedge clk)
 
        if (ce & latch_res) res <= o1;
 
 
wire [7:0] maxdivcnt;
wire [7:0] maxdivcnt;
generate begin
generate begin
if (WID==128) begin
if (WID==128) begin
    assign inf = &fpu_o[126:112] && fpu_o[111:0]==0;
    assign inf = &fpu_o[126:112] && fpu_o[111:0]==0;
    assign subinf       = fpu_o[126:0]==`QSUBINFQ;
    assign subinf       = fpu_o[126:0]==`QSUBINFQ;
    assign infdiv       = fpu_o[126:0]==`QINFDIVQ;
    assign infdiv       = fpu_o[126:0]==`QINFDIVQ;
    assign zerozero = fpu_o[126:0]==`QZEROZEROQ;
    assign zerozero = fpu_o[126:0]==`QZEROZEROQ;
    assign infzero      = fpu_o[126:0]==`QINFZEROQ;
    assign infzero      = fpu_o[126:0]==`QINFZEROQ;
    assign maxdivcnt = 8'd250;
    assign maxdivcnt = 8'd128;
end
end
else if (WID==80) begin
else if (WID==80) begin
    assign inf = &fpu_o[78:64] && fpu_o[63:0]==0;
    assign inf = &fpu_o[78:64] && fpu_o[63:0]==0;
    assign subinf       = fpu_o[78:0]==`QSUBINFDX;
    assign subinf       = fpu_o[78:0]==`QSUBINFDX;
    assign infdiv       = fpu_o[78:0]==`QINFDIVDX;
    assign infdiv       = fpu_o[78:0]==`QINFDIVDX;
    assign zerozero = fpu_o[78:0]==`QZEROZERODX;
    assign zerozero = fpu_o[78:0]==`QZEROZERODX;
    assign infzero      = fpu_o[78:0]==`QINFZERODX;
    assign infzero      = fpu_o[78:0]==`QINFZERODX;
    assign maxdivcnt = 8'd136;
    assign maxdivcnt = 8'd80;
end
end
else if (WID==64) begin
else if (WID==64) begin
    assign inf      = &fpu_o[62:52] && fpu_o[51:0]==0;
    assign inf      = &fpu_o[62:52] && fpu_o[51:0]==0;
    assign subinf   = fpu_o[62:0]==`QSUBINFD;
    assign subinf   = fpu_o[62:0]==`QSUBINFD;
    assign infdiv   = fpu_o[62:0]==`QINFDIVD;
    assign infdiv   = fpu_o[62:0]==`QINFDIVD;
    assign zerozero = fpu_o[62:0]==`QZEROZEROD;
    assign zerozero = fpu_o[62:0]==`QZEROZEROD;
    assign infzero  = fpu_o[62:0]==`QINFZEROD;
    assign infzero  = fpu_o[62:0]==`QINFZEROD;
    assign maxdivcnt = 8'd112;
    assign maxdivcnt = 8'd64;
end
end
else if (WID==32) begin
else if (WID==32) begin
    assign inf      = &fpu_o[30:23] && fpu_o[22:0]==0;
    assign inf      = &fpu_o[30:23] && fpu_o[22:0]==0;
    assign subinf   = fpu_o[30:0]==`QSUBINFS;
    assign subinf   = fpu_o[30:0]==`QSUBINFS;
    assign infdiv   = fpu_o[30:0]==`QINFDIVS;
    assign infdiv   = fpu_o[30:0]==`QINFDIVS;
    assign zerozero = fpu_o[30:0]==`QZEROZEROS;
    assign zerozero = fpu_o[30:0]==`QZEROZEROS;
    assign infzero  = fpu_o[30:0]==`QINFZEROS;
    assign infzero  = fpu_o[30:0]==`QINFZEROS;
    assign maxdivcnt = 8'd54;
    assign maxdivcnt = 8'd32;
end
end
end
end
endgenerate
endgenerate
 
 
assign exception = gx;
assign exception = gx;
Line 562... Line 606...
always @(posedge clk)
always @(posedge clk)
begin
begin
    if (rst)
    if (rst)
        fpcnt <= 8'h00;
        fpcnt <= 8'h00;
    else begin
    else begin
    if (ld)
  if (ld|rem_ld)
        case(ir[5:0])
    case(op4)
        `FLOAT:
    `FLT3:
            begin
        case(func6b)
 
        `FMA:           fpcnt <= 8'd22;
 
        `FMS:           fpcnt <= 8'd22;
 
        `FNMA:  fpcnt <= 8'd22;
 
        `FNMS:  fpcnt <= 8'd22;
 
        default:        fpcnt <= 8'd00;
 
        endcase
 
    `FLT2,`FLT2LI:
 
      case(func6b)
 
      `FCMP:  begin fpcnt <= 8'd0; end
 
      `FADD:  begin fpcnt <= 8'd6; end
 
      `FSUB:  begin fpcnt <= 8'd6; end
 
      `FMUL:  begin fpcnt <= 8'd6; end
 
      `FDIV:  begin fpcnt <= maxdivcnt; end
 
      `FREM:    fpcnt <= maxdivcnt+8'd23;
 
      `NXTAFT: fpcnt <= 8'd1;
 
      `FSCALEB: fpcnt <= 8'd2;
 
      default:    fpcnt <= 8'h00;
 
      endcase
 
    `FLT1:
                case(func6b)
                case(func6b)
                `FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,
                `FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,
                `FCVTSD,`FCVTSQ,`FCVTDS:  begin fpcnt <= 8'd0; end
      `FCVTSD,`FCVTDS:  begin fpcnt <= 8'd0; end
                `FTOI:  begin fpcnt <= 8'd1; end
                `FTOI:  begin fpcnt <= 8'd1; end
                `ITOF:  begin fpcnt <= 8'd1; end
                `ITOF:  begin fpcnt <= 8'd1; end
                `FCMP:  begin fpcnt <= 8'd0; end
      `TRUNC:  begin fpcnt <= 8'd1; end
                `FADD:  begin fpcnt <= 8'd8; end
      `FSQRT: begin fpcnt <= maxdivcnt; end
                `FSUB:  begin fpcnt <= 8'd8; end
 
                `FMUL:  begin fpcnt <= 8'd10; end
 
                `FDIV:  begin fpcnt <= maxdivcnt; end
 
                default:    fpcnt <= 8'h00;
                default:    fpcnt <= 8'h00;
                endcase
                endcase
            end
    `FLT1A:
        `VECTOR:
 
            case(func6b)
            case(func6b)
            `VFNEG:  begin fpcnt <= 8'd0; end
        `FRES:  fpcnt <= 8'h03;
            `VFADD:  begin fpcnt <= 8'd8; end
 
            `VFSUB:  begin fpcnt <= 8'd8; end
 
            `VFSxx:  begin fpcnt <= 8'd0; end
 
            `VFMUL:  begin fpcnt <= 8'd10; end
 
            `VFDIV:  begin fpcnt <= maxdivcnt; end
 
            `VFTOI:  begin fpcnt <= 8'd1; end
 
            `VITOF:  begin fpcnt <= 8'd1; end
 
            default:    fpcnt <= 8'h00;
            default:    fpcnt <= 8'h00;
            endcase
            endcase
        default:    fpcnt <= 8'h00;
        default:    fpcnt <= 8'h00;
        endcase
        endcase
    else if (!done)
  else if (!op_done) begin
 
        if ((op4==`FLT2||op4==`FLT2LI) && func6b==`FDIV && divDone)
 
                fpcnt <= 8'h00;
 
        else
        fpcnt <= fpcnt - 1;
        fpcnt <= fpcnt - 1;
    end
    end
end
end
 
end
endmodule
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.