1 |
9 |
robfinch |
`timescale 1ns / 1ps
|
2 |
|
|
// ============================================================================
|
3 |
|
|
// __
|
4 |
26 |
robfinch |
// \\__/ o\ (C) 2007-2019 Robert Finch, Waterloo
|
5 |
9 |
robfinch |
// \ __ / All rights reserved.
|
6 |
|
|
// \/_// robfinch<remove>@finitron.ca
|
7 |
|
|
// ||
|
8 |
|
|
//
|
9 |
|
|
// fpZLUnit.v
|
10 |
|
|
// - zero latency floating point unit
|
11 |
|
|
// - instructions can execute in a single cycle without
|
12 |
|
|
// a clock
|
13 |
|
|
// - parameterized width
|
14 |
|
|
// - IEEE 754 representation
|
15 |
|
|
//
|
16 |
|
|
//
|
17 |
|
|
// This source file is free software: you can redistribute it and/or modify
|
18 |
|
|
// it under the terms of the GNU Lesser General Public License as published
|
19 |
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
20 |
|
|
// (at your option) any later version.
|
21 |
|
|
//
|
22 |
|
|
// This source file is distributed in the hope that it will be useful,
|
23 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
24 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
25 |
|
|
// GNU General Public License for more details.
|
26 |
|
|
//
|
27 |
|
|
// You should have received a copy of the GNU General Public License
|
28 |
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
29 |
|
|
//
|
30 |
|
|
// fabs - get absolute value of number
|
31 |
|
|
// fnabs - get negative absolute value of number
|
32 |
|
|
// fneg - negate number
|
33 |
|
|
// fmov - copy input to output
|
34 |
|
|
// fsign - get sign of number (set number to +1,0, or -1)
|
35 |
|
|
// fman - get mantissa (set exponent to zero)
|
36 |
|
|
// fcmp
|
37 |
|
|
//
|
38 |
|
|
// ============================================================================
|
39 |
|
|
|
40 |
26 |
robfinch |
`define FLOAT 4'h1
|
41 |
|
|
`define FLT1 4'h1
|
42 |
|
|
`define FLT2 4'h2
|
43 |
|
|
`define FLT3 4'h3
|
44 |
|
|
`define FANDI 4'hE
|
45 |
|
|
`define FORI 4'hF
|
46 |
9 |
robfinch |
|
47 |
26 |
robfinch |
`define FMAX 5'h10
|
48 |
|
|
`define FMIN 5'h11
|
49 |
|
|
`define FCMP 5'h06
|
50 |
|
|
`define FMOV 5'h00
|
51 |
|
|
`define FNEG 5'h04
|
52 |
|
|
`define FABS 5'h05
|
53 |
|
|
`define FSIGN 5'h06
|
54 |
|
|
`define FMAN 5'h07
|
55 |
|
|
`define FNABS 5'h08
|
56 |
|
|
`define FCVTSD 5'h09
|
57 |
|
|
`define F32TO80 5'h0A
|
58 |
|
|
`define ISNAN 5'h0E
|
59 |
|
|
`define CPYSGN 5'h0F // FLT2
|
60 |
|
|
`define FINITE 5'h0F // FLT1
|
61 |
|
|
//`define FCVTSQ 6'h1B
|
62 |
|
|
`define FCVTDS 5'h19
|
63 |
|
|
`define FSLT 5'h10
|
64 |
|
|
`define FSGE 5'h11
|
65 |
|
|
`define FSLE 5'h12
|
66 |
|
|
`define FSGT 5'h13
|
67 |
|
|
`define FSEQ 5'h14
|
68 |
|
|
`define FSNE 5'h15
|
69 |
|
|
`define FSUN 5'h16
|
70 |
|
|
`define F80TO32 5'h1A
|
71 |
|
|
`define UNORD 5'h1F
|
72 |
|
|
|
73 |
9 |
robfinch |
module fpZLUnit
|
74 |
26 |
robfinch |
#(parameter WID=80)
|
75 |
9 |
robfinch |
(
|
76 |
26 |
robfinch |
input [3:0] op4,
|
77 |
|
|
input [4:0] func5,
|
78 |
|
|
input [39:0] ir,
|
79 |
|
|
input [WID+3:0] a,
|
80 |
|
|
input [WID+3:0] b, // for fcmp
|
81 |
|
|
input [WID+3:0] c, // for fcmp
|
82 |
|
|
output reg [WID+3:0] o,
|
83 |
|
|
output reg nanx
|
84 |
9 |
robfinch |
);
|
85 |
26 |
robfinch |
`include "fpSize.sv"
|
86 |
9 |
robfinch |
|
87 |
26 |
robfinch |
//wire [1:0] prec = ir[25:24];
|
88 |
9 |
robfinch |
|
89 |
26 |
robfinch |
wire nanxab,nanxac,nanxbc;
|
90 |
|
|
wire nana;
|
91 |
|
|
wire [EMSB:0] expa;
|
92 |
|
|
wire [FMSB:0] ma;
|
93 |
|
|
wire xinfa;
|
94 |
|
|
wire [4:0] cmp_o, cmpac_o, cmpbc_o;
|
95 |
9 |
robfinch |
|
96 |
26 |
robfinch |
// Zero is being passed for b in some cases so the NaN must come from a if
|
97 |
|
|
// present.
|
98 |
|
|
fp_cmp_unit #(WID+4) u1 (.a(a), .b(b), .o(cmp_o), .nanx(nanxab) );
|
99 |
|
|
fp_cmp_unit #(WID+4) u2 (.a(a), .b(c), .o(cmpac_o), .nanx(nanxac) );
|
100 |
|
|
fp_cmp_unit #(WID+4) u3 (.a(b), .b(c), .o(cmpbc_o), .nanx(nanxbc) );
|
101 |
|
|
fpDecomp #(WID+4) u4 (.i(a), .sgn(), .exp(expa), .man(ma), .fract(), .xz(), .mz(), .vz(), .inf(), .xinf(xinfa), .qnan(), .snan(), .nan(nana));
|
102 |
9 |
robfinch |
wire [127:0] sq_o;
|
103 |
26 |
robfinch |
//fcvtsq u2 (a[31:0], sq_o);
|
104 |
|
|
wire [79:0] sdo;
|
105 |
|
|
fs2d u5 (a[43:4], sdo);
|
106 |
|
|
wire [39:0] dso;
|
107 |
|
|
fd2s u6 (a, dso);
|
108 |
|
|
wire [79:0] f32to80o;
|
109 |
|
|
wire [31:0] f80to32o;
|
110 |
|
|
F32ToF80 u7 (a[35:4], f32to80o);
|
111 |
|
|
F80ToF32 u8 (a[WID+3:4], f32to80o);
|
112 |
9 |
robfinch |
|
113 |
|
|
always @*
|
114 |
26 |
robfinch |
case(op4)
|
115 |
|
|
`FLT1:
|
116 |
|
|
case(func5)
|
117 |
|
|
`FABS: begin o <= {1'b0,a[WID-2:0]}; nanx <= nanxab; end
|
118 |
|
|
`FNABS: begin o <= {1'b1,a[WID-2:0]}; nanx <= nanxab; end
|
119 |
|
|
`FNEG: begin o <= {~a[WID-1],a[WID-2:0]}; nanx <= nanxab; end
|
120 |
|
|
`FMOV: begin o <= a; nanx <= nanxab; end
|
121 |
|
|
`FSIGN: begin o <= (a[WID-2:0]==0) ? 0 : {a[WID-1],1'b0,{EMSB{1'b1}},{FMSB+1{1'b0}}}; nanx <= 1'b0; end
|
122 |
|
|
`FMAN: begin o <= {a[WID-1],1'b0,{EMSB{1'b1}},a[FMSB:0]}; nanx <= 1'b0; end
|
123 |
|
|
//`FCVTSQ: o <= sq_o;
|
124 |
|
|
`FCVTSD: begin o <= {sdo,4'h0}; nanx <= nanxab; end
|
125 |
|
|
`FCVTDS: begin o <= {{40{dso[39]}},dso,4'h0}; nanx <= nanxab; end
|
126 |
|
|
`F32TO80: begin o <= {f32to80o,4'h0}; nanx <= nanxab; end
|
127 |
|
|
`F80TO32: begin o <= {f80to32o,4'h0}; nanx <= nanxab; end
|
128 |
|
|
`ISNAN: begin o <= nana; end
|
129 |
|
|
`FINITE: begin o <= !xinfa; end
|
130 |
|
|
`UNORD: begin o <= nanxab; end
|
131 |
|
|
default: o <= 0;
|
132 |
|
|
endcase
|
133 |
|
|
`FLT2:
|
134 |
|
|
case(func5)
|
135 |
|
|
`FCMP: begin o <= {cmp_o,4'h0}; nanx <= nanxab; end
|
136 |
|
|
`FSLT: begin o <= {cmp_o[1],4'h0}; nanx <= nanxab; end
|
137 |
|
|
`FSGE: begin o <= {~cmp_o[1],4'h0}; nanx <= nanxab; end
|
138 |
|
|
`FSLE: begin o <= {cmp_o[2],4'h0}; nanx <= nanxab; end
|
139 |
|
|
`FSGT: begin o <= ~{cmp_o[2],4'h0}; nanx <= nanxab; end
|
140 |
|
|
`FSEQ: begin o <= {cmp_o[0],4'h0}; nanx <= nanxab; end
|
141 |
|
|
`FSNE: begin o <= ~{cmp_o[0],4'h0}; nanx <= nanxab; end
|
142 |
|
|
`FSUN: begin o <= {cmp_o[4],4'h0}; nanx <= nanxab; end
|
143 |
|
|
`CPYSGN: begin o <= {b[WID+3],a[WID+2:0]}; end
|
144 |
|
|
default: o <= 0;
|
145 |
|
|
endcase
|
146 |
|
|
`FLT3:
|
147 |
|
|
case(func5)
|
148 |
|
|
`FMAX:
|
149 |
|
|
begin
|
150 |
|
|
o <= ~cmp_o[2] & ~cmpac_o[2] ? a : ~cmpbc_o[2] ? b : c;
|
151 |
|
|
nanx <= nanxab|nanxac|nanxbc;
|
152 |
|
|
end
|
153 |
|
|
`FMIN:
|
154 |
|
|
begin
|
155 |
|
|
o <= cmp_o[1] & cmpac_o[1] ? a : cmpbc_o[2] ? b : c;
|
156 |
|
|
nanx <= nanxab|nanxac|nanxbc;
|
157 |
|
|
end
|
158 |
|
|
default: o <= 0;
|
159 |
|
|
endcase
|
160 |
|
|
`FANDI:
|
161 |
|
|
begin
|
162 |
|
|
case(ir[32:31])
|
163 |
|
|
2'd0: o <= {a[23: 4] & {{58{1'b1}},ir[39:33],ir[30:16],4'h0}};
|
164 |
|
|
2'd1: o <= a[43:24] & {{36{1'b1}},ir[39:33],ir[30:16],{20{1'b1}}};
|
165 |
|
|
2'd2: o <= a[63:44] & {{14{1'b1}},ir[39:33],ir[30:16],{40{1'b1}}};
|
166 |
|
|
2'd3: o <= a[83:64] & {ir[39:33],ir[30:16],{60{1'b1}}};
|
167 |
|
|
endcase
|
168 |
|
|
nanx <= 1'b0;
|
169 |
|
|
end
|
170 |
|
|
`FORI:
|
171 |
|
|
begin
|
172 |
|
|
case(ir[32:31])
|
173 |
|
|
2'd0: o <= {a[23: 4] & {{58{1'b0}},ir[39:33],ir[30:16],4'h0}};
|
174 |
|
|
2'd1: o <= a[43:24] & {{36{1'b0}},ir[39:33],ir[30:16],{20{1'b0}}};
|
175 |
|
|
2'd2: o <= a[63:44] & {{14{1'b0}},ir[39:33],ir[30:16],{40{1'b0}}};
|
176 |
|
|
2'd3: o <= a[83:64] & {ir[39:33],ir[30:16],{60{1'b0}}};
|
177 |
|
|
endcase
|
178 |
|
|
nanx <= 1'b0;
|
179 |
|
|
end
|
180 |
9 |
robfinch |
default: o <= 0;
|
181 |
|
|
endcase
|
182 |
|
|
|
183 |
|
|
endmodule
|