Line 1... |
Line 1... |
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ 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
|
// ||
|
// ||
|
//
|
//
|
// 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 67... |
Line 67... |
// related integer:
|
// related integer:
|
// graf ; 1 0 get random float (0,1]
|
// graf ; 1 0 get random float (0,1]
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`define FLOAT 6'h36
|
`define TRUE 1'b1
|
`define FMOV 6'h00
|
`define FALSE 1'b0
|
`define FTOI 6'h02
|
|
`define ITOF 6'h03
|
`define VECTOR 6'h01
|
`define FNEG 6'h04
|
`define VFABS 6'h03
|
`define FABS 6'h05
|
`define VFADD 6'h04
|
`define FSIGN 6'h06
|
`define VFSUB 6'h05
|
`define FMAN 6'h07
|
`define VFSxx 6'h06
|
`define FNABS 6'h08
|
`define VFNEG 6'h16
|
`define FCVTSQ 6'h0B
|
`define VFTOI 6'h24
|
`define FSTAT 6'h0C
|
`define VITOF 6'h25
|
`define FTX 6'h10
|
`define VFMUL 6'h3A
|
`define FCX 6'h11
|
`define VFDIV 6'h3E
|
`define FEX 6'h12
|
`define FLOAT 6'h0B
|
`define FDX 6'h13
|
`define FMOV 6'h10
|
`define FRM 6'h14
|
`define FTOI 6'h12
|
|
`define ITOF 6'h13
|
`define FCMP 3'h1
|
`define FNEG 6'h14
|
`define FADD 3'h4
|
`define FABS 6'h15
|
`define FSUB 3'h5
|
`define FSIGN 6'h16
|
`define FMUL 3'h6
|
`define FMAN 6'h17
|
`define FDIV 3'h7
|
`define FNABS 6'h18
|
|
`define FCVTSD 6'h19
|
|
`define FCVTSQ 6'h1B
|
|
`define FSTAT 6'h1C
|
|
`define FTX 6'h20
|
|
`define FCX 6'h21
|
|
`define FEX 6'h22
|
|
`define FDX 6'h23
|
|
`define FRM 6'h24
|
|
`define FCVTDS 6'h29
|
|
|
|
`define FADD 6'h04
|
|
`define FSUB 6'h05
|
|
`define FCMP 6'h06
|
|
`define FMUL 6'h08
|
|
`define FDIV 6'h09
|
|
|
`define QINFOS 23'h7FC000 // info
|
`define QINFOS 23'h7FC000 // info
|
`define QSUBINFS 31'h7FC00001 // - infinity - infinity
|
`define QSUBINFS 31'h7FC00001 // - infinity - infinity
|
`define QINFDIVS 31'h7FC00002 // - infinity / infinity
|
`define QINFDIVS 31'h7FC00002 // - infinity / infinity
|
`define QZEROZEROS 31'h7FC00003 // - zero / zero
|
`define QZEROZEROS 31'h7FC00003 // - zero / zero
|
Line 114... |
Line 129... |
`define QSUBINFQ 127'h7F_FF00000000_0000000000_0000000001 // - infinity - infinity
|
`define QSUBINFQ 127'h7F_FF00000000_0000000000_0000000001 // - infinity - infinity
|
`define QINFDIVQ 127'h7F_FF00000000_0000000000_0000000002 // - infinity / infinity
|
`define QINFDIVQ 127'h7F_FF00000000_0000000000_0000000002 // - infinity / infinity
|
`define QZEROZEROQ 127'h7F_FF00000000_0000000000_0000000003 // - zero / zero
|
`define QZEROZEROQ 127'h7F_FF00000000_0000000000_0000000003 // - zero / zero
|
`define QINFZEROQ 127'h7F_FF00000000_0000000000_0000000004 // - infinity X zero
|
`define QINFZEROQ 127'h7F_FF00000000_0000000000_0000000004 // - infinity X zero
|
|
|
module fpUnit(rst, clk, ce, ir, ld, a, b, imm, o, status, exception, done);
|
module fpUnit(rst, clk, ce, ir, ld, a, b, imm, o, csr_i, status, exception, done, rm
|
|
);
|
|
|
parameter WID = 128;
|
parameter WID = 64;
|
localparam MSB = WID-1;
|
localparam MSB = WID-1;
|
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 :
|
Line 156... |
Line 172... |
input ld;
|
input ld;
|
input [MSB:0] a;
|
input [MSB:0] a;
|
input [MSB:0] b;
|
input [MSB:0] b;
|
input [5:0] imm;
|
input [5:0] imm;
|
output tri [MSB:0] o;
|
output tri [MSB:0] o;
|
|
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;
|
|
|
reg [7:0] fpcnt;
|
reg [7:0] fpcnt;
|
assign done = fpcnt==8'h00;
|
assign done = fpcnt==8'h00;
|
|
|
//------------------------------------------------------------
|
//------------------------------------------------------------
|
Line 183... |
Line 200... |
wire isNan,isNans;
|
wire isNan,isNans;
|
wire nanx,nanxs;
|
wire nanx,nanxs;
|
|
|
// Decode fp operation
|
// Decode fp operation
|
wire [5:0] op = ir[5:0];
|
wire [5:0] op = ir[5:0];
|
wire [5:0] func6b = ir[17:12];
|
wire [5:0] func6b = ir[31:26];
|
wire [1:0] prec = ir[28:27];
|
wire [1:0] prec = ir[25:24];
|
wire [2:0] func3 = ir[31:29];
|
|
wire fstat = {op,func3,func6b} == {`FLOAT,3'b000,`FSTAT}; // get status
|
|
wire fdiv = {op,func3} == {`FLOAT,`FDIV};
|
|
wire ftx = {op,func3,func6b} == {`FLOAT,3'b000,`FTX}; // trigger exception
|
|
wire fcx = {op,func3,func6b} == {`FLOAT,3'b000,`FCX}; // clear exception
|
|
wire fex = {op,func3,func6b} == {`FLOAT,3'b000,`FEX}; // enable exception
|
|
wire fdx = {op,func3,func6b} == {`FLOAT,3'b000,`FDX}; // disable exception
|
|
wire fcmp = {op,func3} == {`FLOAT,`FCMP};
|
|
wire frm = {op,func3,func6b} == {`FLOAT,3'b000,`FRM}; // set rounding mode
|
|
|
|
wire zl_op = (op==`FLOAT && ((func3==3'b000 &&
|
wire fstat = {op,func6b} == {`FLOAT,`FSTAT}; // get status
|
|
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 && (
|
(func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN || func6b==`FCVTSQ)) ||
|
(func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN || func6b==`FCVTSQ)) ||
|
func3==`FCMP));
|
func6b==`FCMP);
|
wire loo_op = (op==`FLOAT && func3==3'b000 && (func6b==`ITOF || func6b==`FTOI));
|
wire loo_op = (op==`FLOAT && (func6b==`ITOF || func6b==`FTOI));
|
wire loo_done;
|
wire loo_done;
|
|
|
wire subinf;
|
wire subinf;
|
wire zerozero;
|
wire zerozero;
|
wire infzero;
|
wire infzero;
|
wire infdiv;
|
wire infdiv;
|
|
|
// floating point control and status
|
// floating point control and status
|
reg [2:0] rm; // rounding mode
|
|
|
wire inexe_i = csr_i[28];
|
|
wire dbzxe_i = csr_i[27];
|
|
wire underxe_i = csr_i[26];
|
|
wire overxe_i = csr_i[25];
|
|
wire invopxe_i = csr_i[24];
|
|
wire fractie_i = csr_i[22];
|
|
wire rawayz_i = csr_i[21];
|
|
wire C_i = csr_i[20];
|
|
wire neg_i = csr_i[19];
|
|
wire pos_i = csr_i[18];
|
|
wire zero_i = csr_i[17];
|
|
wire inf_i = csr_i[16];
|
|
wire swt_i = csr_i[15];
|
|
wire inex_i = csr_i[14];
|
|
wire dbzx_i = csr_i[13];
|
|
wire underx_i = csr_i[12];
|
|
wire overx_i = csr_i[11];
|
|
wire giopx_i = csr_i[10];
|
|
wire gx_i = csr_i[9];
|
|
wire sumx_i = csr_i[8];
|
|
wire cvt_i = csr_i[7];
|
|
wire sqrtx_i = csr_i[6];
|
|
wire NaNCmpx_i = csr_i[5];
|
|
wire infzerox_i = csr_i[4];
|
|
wire zerozerox_i= csr_i[3];
|
|
wire infdivx_i = csr_i[2];
|
|
wire subinfx_i = csr_i[1];
|
|
wire snanx_i = csr_i[0];
|
reg inexe; // inexact exception enable
|
reg inexe; // inexact exception enable
|
reg dbzxe; // divide by zero exception enable
|
reg dbzxe; // divide by zero exception enable
|
reg underxe; // underflow exception enable
|
reg underxe; // underflow exception enable
|
reg overxe; // overflow exception enable
|
reg overxe; // overflow exception enable
|
reg invopxe; // invalid operation exception enable
|
reg invopxe; // invalid operation exception enable
|
Line 248... |
Line 293... |
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)
|
// reset: disable and clear all exceptions and status
|
// reset: disable and clear all exceptions and status
|
if (rst) begin
|
if (rst) begin
|
rm <= 2'b0; // round nearest even - default rounding mode
|
|
inex <= 1'b0;
|
inex <= 1'b0;
|
dbzx <= 1'b0;
|
dbzx <= 1'b0;
|
underx <= 1'b0;
|
underx <= 1'b0;
|
overx <= 1'b0;
|
overx <= 1'b0;
|
giopx <= 1'b0;
|
giopx <= 1'b0;
|
Line 283... |
Line 326... |
fractie <= 1'b0;
|
fractie <= 1'b0;
|
snanx <= 1'b0;
|
snanx <= 1'b0;
|
end
|
end
|
else if (pipe_ce) begin
|
else if (pipe_ce) begin
|
if (ftx && precmatch) begin
|
if (ftx && precmatch) begin
|
inex <= inex | (a[4]|imm[4]);
|
inex <= (a[4]|imm[4]);
|
dbzx <= dbzx | (a[3]|imm[3]);
|
dbzx <= (a[3]|imm[3]);
|
underx <= underx | (a[2]|imm[2]);
|
underx <= (a[2]|imm[2]);
|
overx <= overx | (a[1]|imm[1]);
|
overx <= (a[1]|imm[1]);
|
giopx <= giopx | (a[0]|imm[0]);
|
giopx <= (a[0]|imm[0]);
|
swtx <= 1'b1;
|
swtx <= 1'b1;
|
sx <= 1'b1;
|
sx <= 1'b1;
|
end
|
end
|
else if (fcx && precmatch) begin
|
|
sx <= sx & !(a[5]|imm[5]);
|
|
inex <= inex & !(a[4]|imm[4]);
|
|
dbzx <= dbzx & !(a[3]|imm[3]);
|
|
underx <= underx & !(a[2]|imm[2]);
|
|
overx <= overx & !(a[1]|imm[1]);
|
|
giopx <= giopx & !(a[0]|imm[0]);
|
|
// clear exception type when global invalid operation is cleared
|
|
infdivx <= infdivx & !(a[0]|imm[0]);
|
|
zerozerox <= zerozerox & !(a[0]|imm[0]);
|
|
subinfx <= subinfx & !(a[0]|imm[0]);
|
|
infzerox <= infzerox & !(a[0]|imm[0]);
|
|
NaNCmpx <= NaNCmpx & !(a[0]|imm[0]);
|
|
dbzx <= dbzx & !(a[0]|imm[0]);
|
|
swtx <= 1'b1;
|
|
end
|
|
else if (fex && precmatch) begin
|
|
inexe <= inexe | (a[4]|imm[4]);
|
|
dbzxe <= dbzxe | (a[3]|imm[3]);
|
|
underxe <= underxe | (a[2]|imm[2]);
|
|
overxe <= overxe | (a[1]|imm[1]);
|
|
invopxe <= invopxe | (a[0]|imm[0]);
|
|
end
|
|
else if (fdx && precmatch) begin
|
|
inexe <= inexe & !(a[4]|imm[4]);
|
|
dbzxe <= dbzxe & !(a[3]|imm[3]);
|
|
underxe <= underxe & !(a[2]|imm[2]);
|
|
overxe <= overxe & !(a[1]|imm[1]);
|
|
invopxe <= invopxe & !(a[0]|imm[0]);
|
|
end
|
|
else if (frm && precmatch)
|
|
rm <= a[2:0]|imm[2:0];
|
|
|
|
infzerox <= infzerox | (invopxe & infzero);
|
infzerox <= infzero & invopxe_i;
|
zerozerox <= zerozerox | (invopxe & zerozero);
|
zerozerox <= zerozero & invopxe_i;
|
subinfx <= subinfx | (invopxe & subinf);
|
subinfx <= subinf & invopxe_i;
|
infdivx <= infdivx | (invopxe & infdiv);
|
infdivx <= infdiv & invopxe_i;
|
dbzx <= dbzx | (dbzxe & divByZero);
|
dbzx <= divByZero & dbzxe_i;
|
NaNCmpx <= NaNCmpx | (invopxe & nanx & fcmp); // must be a compare
|
NaNCmpx <= nanx & fcmp & invopxe_i; // must be a compare
|
sx <= sx |
|
// sx <= sx |
|
(invopxe & nanx & fcmp) |
|
// (invopxe & nanx & fcmp) |
|
(invopxe & (infzero|zerozero|subinf|infdiv)) |
|
// (invopxe & (infzero|zerozero|subinf|infdiv)) |
|
(dbzxe & divByZero);
|
// (dbzxe & divByZero);
|
snanx <= isNan;
|
snanx <= isNan & invopxe_i;
|
end
|
end
|
|
|
// Decompose operands into sign,exponent,mantissa
|
// Decompose operands into sign,exponent,mantissa
|
wire sa, sb, sas, sbs;
|
wire sa, sb, sas, sbs;
|
wire [FMSB:0] ma, mb;
|
wire [FMSB:0] ma, mb;
|
Line 346... |
Line 357... |
|
|
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 [7:0] op1, op2;
|
wire [5:0] op1, op2;
|
wire [5:0] fn1;
|
wire [5:0] fn2;
|
wire [2: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 [127:0] zlq_o;
|
wire [WID-1:0] zlq_o, looq_o;
|
fpZLUnit #(WID) u6 (.ir(ir), .a(a), .b(b), .o(zlq_o), .nanx(nanx) );
|
fpZLUnit #(WID) u6 (.ir(ir), .a(a), .b(b), .o(zlq_o), .nanx(nanx) );
|
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .ir(ir), .a(a), .o(looq_o), .done(looq_done) );
|
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .ir(ir), .a(a), .o(looq_o), .done() );
|
//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() );
|
assign zl_o = zlq_o;
|
|
assign loo_o = looq_o;
|
|
|
|
fp_decomp #(WID) u1 (.i(a), .sgn(sa), .man(ma), .vz(az), .inf(aInf), .nan(aNan) );
|
fp_decomp #(WID) u1 (.i(a), .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(b), .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[26:24]==3'b111 ? rm : ir[26:24];
|
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 #(6) u5 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op2) );
|
delay1 #(3) u5a (.clk(clk), .ce(pipe_ce), .i(func3), .o(fn1) );
|
delay2 #(6) u5b (.clk(clk), .ce(pipe_ce), .i(func6b), .o(fn2) );
|
delay2 #(3) u5b (.clk(clk), .ce(pipe_ce), .i(func3), .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
|
wire aob_nan = aNan|bNan; // one of the operands is a nan
|
wire aob_nan = aNan|bNan; // one of the operands is a nan
|
Line 407... |
Line 414... |
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;
|
|
|
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func3[0]), .a(a), .b(b), .o(fas_o) );
|
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func6b[0]), .a(a), .b(b), .o(fas_o) );
|
fpDiv #(WID) u11(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a), .b(b), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
|
fpDiv #(WID) u11(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a), .b(b), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
|
fpMul #(WID) u12(.clk(clk), .ce(pipe_ce), .a(a), .b(b), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
|
fpMul #(WID) u12(.clk(clk), .ce(pipe_ce), .a(a), .b(b), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
|
/*
|
/*
|
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 @(fn2,mulUnder,divUnder,mulUnders,divUnders)
|
always @*
|
|
case(op2)
|
|
`FLOAT:
|
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
|
|
endcase
|
|
|
always @(fn2,fas_o,fmul_o,fdiv_o,fass_o,fmuls_o,fdivs_o)
|
always @*
|
|
case(op2)
|
|
`FLOAT:
|
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;
|
default: begin fres <= fas_o; fress <= fass_o; end
|
default: begin fres <= fas_o; fress <= fass_o; end
|
endcase
|
endcase
|
|
`VECTOR:
|
|
case(fn2)
|
|
`VFADD: fres <= fas_o;
|
|
`VFSUB: fres <= fas_o;
|
|
`VFMUL: fres <= fmul_o;
|
|
`VFDIV: fres <= fdiv_o;
|
|
default: begin fres <= fas_o; fress <= fass_o; end
|
|
endcase
|
|
default: begin fres <= fas_o; fress <= fass_o; end
|
|
endcase
|
|
|
// pipeline stage
|
// pipeline stage
|
// one cycle latency
|
// one cycle latency
|
fpNormalize #(WID) fpn0(.clk(clk), .ce(pipe_ce), .under(under), .i(fres), .o(fpn_o) );
|
fpNormalize #(WID) fpn0(.clk(clk), .ce(pipe_ce), .under(under), .i(fres), .o(fpn_o) );
|
//fpNormalize #(32) fpns(.clk(clk), .ce(pipe_ce), .under(unders), .i(fress), .o(fpns_o) );
|
//fpNormalize #(32) fpns(.clk(clk), .ce(pipe_ce), .under(unders), .i(fress), .o(fpns_o) );
|
|
|
// pipeline stage
|
// pipeline stage
|
// one cycle latency
|
// one cycle latency
|
fpRoundReg #(WID) fpr0(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpn_o), .o(fpu_o) );
|
fpRoundReg #(WID) fpr0(.clk(clk), .ce(pipe_ce), .rm(rmd4), .i(fpn_o), .o(fpu_o) );
|
//fpRoundReg #(32) fprs(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpns_o), .o(fpus_o) );
|
//fpRoundReg #(32) fprs(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpns_o), .o(fpus_o) );
|
|
|
wire so = (isNan?nso:fpu_o[WID-1]);
|
wire so = (isNan?nso:fpu_o[WID-1]);
|
//single ? (isNans?nsos:fpus_o[31]): (isNan?nso:fpu_o[63]);
|
//single ? (isNans?nsos:fpus_o[31]): (isNan?nso:fpu_o[63]);
|
|
|
Line 471... |
Line 500... |
overx,
|
overx,
|
giopx,
|
giopx,
|
gx,
|
gx,
|
sx,
|
sx,
|
|
|
cvtx,
|
1'b0, // cvtx
|
sqrtx,
|
1'b0, // sqrtx
|
NaNCmpx,
|
fcmp & nanx,
|
infzerox,
|
infzero,
|
zerozerox,
|
zerozero,
|
infdivx,
|
infdiv,
|
subinfx,
|
subinf,
|
snanx
|
isNan
|
};
|
};
|
|
|
assign o = (!fstat) ?
|
assign o = (!fstat) ?
|
|
(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]} : 'bz;
|
assign zero = fpu_o[MSB-1:0]==0;
|
assign zero = fpu_o[MSB-1:0]==0;
|
|
|
Line 536... |
Line 566... |
else begin
|
else begin
|
if (ld)
|
if (ld)
|
case(ir[5:0])
|
case(ir[5:0])
|
`FLOAT:
|
`FLOAT:
|
begin
|
begin
|
case(ir[31:29])
|
case(func6b)
|
3'd0:
|
`FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,
|
case(ir[23:18])
|
`FCVTSD,`FCVTSQ,`FCVTDS: begin fpcnt <= 8'd0; end
|
`FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,`FCVTSQ: 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
|
default: fpcnt <= 8'h00;
|
|
endcase
|
|
`FCMP: begin fpcnt <= 8'd0; end
|
`FCMP: begin fpcnt <= 8'd0; end
|
`FADD: begin fpcnt <= 8'd8; end
|
`FADD: begin fpcnt <= 8'd8; end
|
`FSUB: begin fpcnt <= 8'd8; end
|
`FSUB: begin fpcnt <= 8'd8; end
|
`FMUL: begin fpcnt <= 8'd10; end
|
`FMUL: begin fpcnt <= 8'd10; end
|
`FDIV: begin fpcnt <= maxdivcnt; end
|
`FDIV: begin fpcnt <= maxdivcnt; end
|
default: fpcnt <= 8'h00;
|
default: fpcnt <= 8'h00;
|
endcase
|
endcase
|
end
|
end
|
|
`VECTOR:
|
|
case(func6b)
|
|
`VFNEG: begin fpcnt <= 8'd0; end
|
|
`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;
|
|
endcase
|
default: fpcnt <= 8'h00;
|
default: fpcnt <= 8'h00;
|
endcase
|
endcase
|
else if (!done)
|
else if (!done)
|
fpcnt <= fpcnt - 1;
|
fpcnt <= fpcnt - 1;
|
end
|
end
|