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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpUnit.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 robfinch
// ============================================================================
2
//        __
3 10 robfinch
//   \\__/ o\    (C) 2006-2018  Robert Finch, Waterloo
4 9 robfinch
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// This source file is free software: you can redistribute it and/or modify 
9
// it under the terms of the GNU Lesser General Public License as published 
10
// by the Free Software Foundation, either version 3 of the License, or     
11
// (at your option) any later version.                                      
12
//                                                                          
13
// This source file is distributed in the hope that it will be useful,      
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
16
// GNU General Public License for more details.                             
17
//                                                                          
18
// You should have received a copy of the GNU General Public License        
19
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
20
//
21
//
22
// DSD
23
//      fpUnit.v
24
//  - floating point unit
25
//  - parameterized width
26
//  - IEEE 754 representation
27
//
28
//      NaN Value               Origin
29
// 31'h7FC00001    - infinity - infinity
30
// 31'h7FC00002    - infinity / infinity
31
// 31'h7FC00003    - zero / zero
32
// 31'h7FC00004    - infinity X zero
33
//
34
// Whenever the fpu encounters a NaN input, the NaN is
35
// passed through to the output.
36
//
37
// Ref: Webpack 8.2  Spartan3-4  xc3s1000-4ft256
38
// 2335 LUTS / 1260 slices / 43.4 MHz
39
// Ref: Webpack 13.1 Spartan3e   xc3s1200e-4fg320
40
// 2433 LUTs / 1301 slices / 51.6 MHz
41
//
42
// Instr.  Cyc Lat
43
// fc__    ; 1  0    compare, lt le gt ge eq ne or un
44
// fabs    ; 1  0     absolute value
45
// fnabs    ; 1  0     negative absolute value
46
// fneg    ; 1  0     negate
47
// fmov    ; 1  0     move
48
// fman    ; 1  0     get mantissa
49
// fsign    ; 1  0     get sign
50
//
51
// f2i        ; 1  1  convert float to integer
52
// i2f        ; 1  1  convert integer to float
53
//
54
// fadd    ; 1  5    addition
55
// fsub    ; 1  5  subtraction
56
// fmul    ; 1  6  multiplication
57
//
58
// fdiv    ; 43 43  division
59
//
60
// ftx        ; 1  0  trigger fp exception
61
// fcx        ; 1  0  clear fp exception
62
// fex        ; 1  0  enable fp exception
63
// fdx        ; 1  0  disable fp exception
64
// frm        ; 1  0  set rounding mode
65
// fstat    ; 1  0  get status register
66
//
67
// related integer:
68
// graf    ; 1  0  get random float (0,1]
69
//
70
// ============================================================================
71
//
72 10 robfinch
`define TRUE    1'b1
73
`define FALSE   1'b0
74 9 robfinch
 
75 10 robfinch
`define VECTOR  6'h01
76
`define VFABS       6'h03
77
`define VFADD       6'h04
78
`define VFSUB       6'h05
79
`define VFSxx       6'h06
80
`define VFNEG       6'h16
81
`define VFTOI       6'h24
82
`define VITOF       6'h25
83
`define VFMUL       6'h3A
84
`define VFDIV       6'h3E
85
`define FLOAT   6'h0B
86
`define FMOV    6'h10
87
`define FTOI    6'h12
88
`define ITOF    6'h13
89
`define FNEG    6'h14
90
`define FABS    6'h15
91
`define FSIGN   6'h16
92
`define FMAN    6'h17
93
`define FNABS   6'h18
94
`define FCVTSD  6'h19
95
`define FCVTSQ  6'h1B
96
`define FSTAT   6'h1C
97
`define FTX     6'h20
98
`define FCX     6'h21
99
`define FEX     6'h22
100
`define FDX     6'h23
101
`define FRM     6'h24
102
`define FCVTDS  6'h29
103 9 robfinch
 
104 10 robfinch
`define FADD    6'h04
105
`define FSUB    6'h05
106
`define FCMP    6'h06
107
`define FMUL    6'h08
108
`define FDIV    6'h09
109
 
110 9 robfinch
`define QINFOS          23'h7FC000              // info
111
`define QSUBINFS        31'h7FC00001    // - infinity - infinity
112
`define QINFDIVS        31'h7FC00002    // - infinity / infinity
113
`define QZEROZEROS      31'h7FC00003    // - zero / zero
114
`define QINFZEROS       31'h7FC00004    // - infinity X zero
115
 
116
`define QINFOD          52'hFF80000000000               // info
117
`define QSUBINFD        63'h7FF0000000000001    // - infinity - infinity
118
`define QINFDIVD        63'h7FF0000000000002    // - infinity / infinity
119
`define QZEROZEROD  63'h7FF0000000000003        // - zero / zero
120
`define QINFZEROD       63'h7FF0000000000004    // - infinity X zero
121
 
122
`define QINFODX         64'hFF800000_00000000           // info
123
`define QSUBINFDX       79'h7FFF000000_0000000001       // - infinity - infinity
124
`define QINFDIVDX       79'h7FFF000000_0000000002       // - infinity / infinity
125
`define QZEROZERODX 79'h7FFF000000_0000000003   // - zero / zero
126
`define QINFZERODX      79'h7FFF000000_0000000004       // - infinity X zero
127
 
128
`define QINFOQ          112'hFF800000_0000000000_0000000000             // info
129
`define QSUBINFQ        127'h7F_FF00000000_0000000000_0000000001        // - infinity - infinity
130
`define QINFDIVQ        127'h7F_FF00000000_0000000000_0000000002        // - infinity / infinity
131
`define QZEROZEROQ  127'h7F_FF00000000_0000000000_0000000003    // - zero / zero
132
`define QINFZEROQ       127'h7F_FF00000000_0000000000_0000000004        // - infinity X zero
133
 
134 10 robfinch
module fpUnit(rst, clk, ce, ir, ld, a, b, imm, o, csr_i, status, exception, done, rm
135
);
136 9 robfinch
 
137 10 robfinch
parameter WID = 64;
138 9 robfinch
localparam MSB = WID-1;
139
localparam EMSB = WID==128 ? 14 :
140
                  WID==96 ? 14 :
141
                  WID==80 ? 14 :
142
                  WID==64 ? 10 :
143
                                  WID==52 ? 10 :
144
                                  WID==48 ? 10 :
145
                                  WID==44 ? 10 :
146
                                  WID==42 ? 10 :
147
                                  WID==40 ?  9 :
148
                                  WID==32 ?  7 :
149
                                  WID==24 ?  6 : 4;
150
localparam FMSB = WID==128 ? 111 :
151
                  WID==96 ? 79 :
152
                  WID==80 ? 63 :
153
                  WID==64 ? 51 :
154
                                  WID==52 ? 39 :
155
                                  WID==48 ? 35 :
156
                                  WID==44 ? 31 :
157
                                  WID==42 ? 29 :
158
                                  WID==40 ? 28 :
159
                                  WID==32 ? 22 :
160
                                  WID==24 ? 15 : 9;
161
localparam EMSBS = 7;
162
localparam FMSBS = 22;
163
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
164
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
165
localparam FXS = (FMSBS+2)*2-1; // the MSB of the expanded fraction
166
localparam EXS = FXS + 1 + EMSBS + 1 + 1 - 1;
167
 
168
input rst;
169
input clk;
170
input ce;
171
input [31:0] ir;
172
input ld;
173
input [MSB:0] a;
174
input [MSB:0] b;
175
input [5:0] imm;
176
output tri [MSB:0] o;
177 10 robfinch
input [31:0] csr_i;
178 9 robfinch
output [31:0] status;
179
output exception;
180
output done;
181 10 robfinch
input [2:0] rm;
182 9 robfinch
 
183
reg [7:0] fpcnt;
184
assign done = fpcnt==8'h00;
185
 
186
//------------------------------------------------------------
187
// constants
188
wire infXpq = {15{1'b1}};
189
wire infXp = {11{1'b1}};        // value for infinite exponent / nan
190
wire infXps = {8{1'b1}};
191
 
192
// Variables
193
wire divByZero;                 // attempt to divide by zero
194
wire inf;                               // result is infinite (+ or -)
195
wire zero;                              // result is zero (+ or -)
196
wire ns;                // nan sign
197
wire nss;
198
wire nso;
199
wire nsos;
200
wire isNan,isNans;
201
wire nanx,nanxs;
202
 
203
// Decode fp operation
204
wire [5:0] op = ir[5:0];
205 10 robfinch
wire [5:0] func6b = ir[31:26];
206
wire [1:0] prec = ir[25:24];
207 9 robfinch
 
208 10 robfinch
wire fstat      = {op,func6b} == {`FLOAT,`FSTAT};       // get status
209
wire fdiv       = {op,func6b} == {`FLOAT,`FDIV};
210
wire ftx        = {op,func6b} == {`FLOAT,`FTX};         // trigger exception
211
wire fcx        = {op,func6b} == {`FLOAT,`FCX};         // clear exception
212
wire fex        = {op,func6b} == {`FLOAT,`FEX};         // enable exception
213
wire fdx        = {op,func6b} == {`FLOAT,`FDX};         // disable exception
214
wire fcmp       = {op,func6b} == {`FLOAT,`FCMP};
215
wire frm        = {op,func6b} == {`FLOAT,`FRM};  // set rounding mode
216
 
217
wire zl_op =  (op==`FLOAT && (
218 9 robfinch
                    (func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN || func6b==`FCVTSQ)) ||
219 10 robfinch
                    func6b==`FCMP);
220
wire loo_op = (op==`FLOAT && (func6b==`ITOF || func6b==`FTOI));
221 9 robfinch
wire loo_done;
222
 
223
wire subinf;
224
wire zerozero;
225
wire infzero;
226
wire infdiv;
227
 
228
// floating point control and status
229 10 robfinch
 
230
wire inexe_i    = csr_i[28];
231
wire dbzxe_i    = csr_i[27];
232
wire underxe_i  = csr_i[26];
233
wire overxe_i   = csr_i[25];
234
wire invopxe_i  = csr_i[24];
235
wire fractie_i  = csr_i[22];
236
wire rawayz_i   = csr_i[21];
237
wire C_i        = csr_i[20];
238
wire neg_i      = csr_i[19];
239
wire pos_i      = csr_i[18];
240
wire zero_i     = csr_i[17];
241
wire inf_i      = csr_i[16];
242
wire swt_i      = csr_i[15];
243
wire inex_i     = csr_i[14];
244
wire dbzx_i     = csr_i[13];
245
wire underx_i   = csr_i[12];
246
wire overx_i    = csr_i[11];
247
wire giopx_i    = csr_i[10];
248
wire gx_i       = csr_i[9];
249
wire sumx_i     = csr_i[8];
250
wire cvt_i      = csr_i[7];
251
wire sqrtx_i    = csr_i[6];
252
wire NaNCmpx_i  = csr_i[5];
253
wire infzerox_i = csr_i[4];
254
wire zerozerox_i= csr_i[3];
255
wire infdivx_i  = csr_i[2];
256
wire subinfx_i  = csr_i[1];
257
wire snanx_i    = csr_i[0];
258 9 robfinch
reg inexe;              // inexact exception enable
259
reg dbzxe;              // divide by zero exception enable
260
reg underxe;    // underflow exception enable
261
reg overxe;             // overflow exception enable
262
reg invopxe;    // invalid operation exception enable
263
 
264
reg nsfp;               // non-standard floating point indicator
265
 
266
reg fractie;    // fraction inexact
267
reg raz;                // rounded away from zero
268
 
269
reg inex;               // inexact exception
270
reg dbzx;               // divide by zero exception
271
reg underx;             // underflow exception
272
reg overx;              // overflow exception
273
reg giopx;              // global invalid operation exception
274
reg sx;                 // summary exception
275
 
276
reg swtx;               // software triggered exception indicator
277
 
278
wire gx = swtx|inex|dbzx|underx|overx|giopx;    // global exception indicator
279
 
280
// breakdown of invalid operation exceptions
281
reg cvtx;               // conversion exception
282
reg sqrtx;              // squareroot exception
283
reg NaNCmpx;    // NaN comparison exception
284
reg infzerox;   // multiply infinity by zero
285
reg zerozerox;  // division of zero by zero
286
reg infdivx;    // division of infinities
287
reg subinfx;    // subtraction of infinities
288
reg snanx;              // signalling nan
289
 
290
wire divDone;
291
wire pipe_ce = ce;// & divDone; // divide must be done in order for pipe to clock
292
wire precmatch = WID==32 ? ir[28:27]==2'b00 :
293
                 WID==64 ? ir[28:27]==2'b01 : 1;
294
                 /*
295
                 WID==80 ? ir[28:27]==2'b10 :
296
                 ir[28:27]==2'b11;
297
                 */
298
always @(posedge clk)
299
        // reset: disable and clear all exceptions and status
300
        if (rst) begin
301
                inex <= 1'b0;
302
                dbzx <= 1'b0;
303
                underx <= 1'b0;
304
                overx <= 1'b0;
305
                giopx <= 1'b0;
306
                swtx <= 1'b0;
307
                sx <= 1'b0;
308
                NaNCmpx <= 1'b0;
309
 
310
                inexe <= 1'b0;
311
                dbzxe <= 1'b0;
312
                underxe <= 1'b0;
313
                overxe <= 1'b0;
314
                invopxe <= 1'b0;
315
 
316
                nsfp <= 1'b0;
317
 
318
                infzerox  <= 1'b0;
319
                zerozerox <= 1'b0;
320
                subinfx   <= 1'b0;
321
                infdivx   <= 1'b0;
322
 
323
        cvtx <= 1'b0;
324
        sqrtx <= 1'b0;
325
        raz <= 1'b0;
326
        fractie <= 1'b0;
327
        snanx <= 1'b0;
328
        end
329
        else if (pipe_ce) begin
330
                if (ftx && precmatch) begin
331 10 robfinch
                        inex <= (a[4]|imm[4]);
332
                        dbzx <= (a[3]|imm[3]);
333
                        underx <= (a[2]|imm[2]);
334
                        overx <= (a[1]|imm[1]);
335
                        giopx <= (a[0]|imm[0]);
336 9 robfinch
                        swtx <= 1'b1;
337
                        sx <= 1'b1;
338
                end
339
 
340 10 robfinch
                infzerox  <= infzero & invopxe_i;
341
                zerozerox <= zerozero & invopxe_i;
342
                subinfx   <= subinf & invopxe_i;
343
                infdivx   <= infdiv & invopxe_i;
344
                dbzx <= divByZero & dbzxe_i;
345
                NaNCmpx <= nanx & fcmp & invopxe_i;     // must be a compare
346
//              sx <= sx |
347
//                              (invopxe & nanx & fcmp) |
348
//                              (invopxe & (infzero|zerozero|subinf|infdiv)) |
349
//                              (dbzxe & divByZero);
350
           snanx <= isNan & invopxe_i;
351 9 robfinch
        end
352
 
353
// Decompose operands into sign,exponent,mantissa
354
wire sa, sb, sas, sbs;
355
wire [FMSB:0] ma, mb;
356
wire [22:0] mas, mbs;
357
 
358
wire aInf, bInf, aInfs, bInfs;
359
wire aNan, bNan, aNans, bNans;
360
wire az, bz, azs, bzs;
361
wire [2:0] rmd4; // 1st stage delayed
362 10 robfinch
wire [5:0] op1, op2;
363
wire [5:0] fn2;
364 9 robfinch
 
365
wire [MSB:0] zld_o,lood_o;
366
wire [31:0] zls_o,loos_o;
367 10 robfinch
wire [WID-1:0] zlq_o, looq_o;
368 9 robfinch
fpZLUnit #(WID) u6 (.ir(ir), .a(a), .b(b), .o(zlq_o), .nanx(nanx) );
369 10 robfinch
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .ir(ir), .a(a), .o(looq_o), .done() );
370 9 robfinch
//fpLOOUnit #(32) u7s (.clk(clk), .ce(pipe_ce), .rm(rm), .op(op), .fn(fn), .a(a[31:0]), .o(loos_o), .done() );
371
 
372
fp_decomp #(WID) u1 (.i(a), .sgn(sa), .man(ma), .vz(az), .inf(aInf), .nan(aNan) );
373
fp_decomp #(WID) u2 (.i(b), .sgn(sb), .man(mb), .vz(bz), .inf(bInf), .nan(bNan) );
374
//fp_decomp #(32) u1s (.i(a[31:0]), .sgn(sas), .man(mas), .vz(azs), .inf(aInfs), .nan(aNans) );
375
//fp_decomp #(32) u2s (.i(b[31:0]), .sgn(sbs), .man(mbs), .vz(bzs), .inf(bInfs), .nan(bNans) );
376
 
377
wire [2:0] rmd = ir[26:24]==3'b111 ? rm : ir[26:24];
378
delay4 #(3) u3 (.clk(clk), .ce(pipe_ce), .i(rmd), .o(rmd4) );
379
delay1 #(6) u4 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op1) );
380
delay2 #(6) u5 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op2) );
381 10 robfinch
delay2 #(6) u5b (.clk(clk), .ce(pipe_ce), .i(func6b), .o(fn2) );
382 9 robfinch
 
383
delay5 delay5_3(.clk(clk), .ce(pipe_ce), .i((bz & !aNan & fdiv)|(bzs & !aNans & fdivs)), .o(divByZero) );
384
 
385
// Compute NaN output sign
386
wire aob_nan = aNan|bNan;       // one of the operands is a nan
387
wire bothNan = aNan&bNan;       // both of the operands are nans
388
//wire aob_nans = aNans|bNans;  // one of the operands is a nan
389
//wire bothNans = aNans&bNans;  // both of the operands are nans
390
 
391
assign ns = bothNan ?
392
                                (ma==mb ? sa & sb : ma < mb ? sb : sa) :
393
                                aNan ? sa : sb;
394
//assign nss = bothNans ?
395
//                                 (mas==mbs ? sas & sbs : mas < mbs ? sbs : sas) :
396
//                                  aNans ? sas : sbs;
397
 
398
delay5 u8(.clk(clk), .ce(ce), .i(ns), .o(nso) );
399
delay5 u9(.clk(clk), .ce(ce), .i(aob_nan), .o(isNan) );
400
//delay5 u8s(.clk(clk), .ce(ce), .i(nss), .o(nsos) );
401
//delay5 u9s(.clk(clk), .ce(ce), .i(aob_nans), .o(isNans) );
402
 
403
wire [MSB:0] fpu_o;
404
wire [MSB+3:0] fpn_o;
405
wire [EX:0] fdiv_o;
406
wire [EX:0] fmul_o;
407
wire [EX:0] fas_o;
408
reg  [EX:0] fres;
409
wire [31:0] fpus_o;
410
wire [31+3:0] fpns_o;
411
wire [EXS:0] fdivs_o;
412
wire [EXS:0] fmuls_o;
413
wire [EXS:0] fass_o;
414
reg  [EXS:0] fress;
415
wire divUnder,divUnders;
416
wire mulUnder,mulUnders;
417
reg under,unders;
418
 
419 10 robfinch
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func6b[0]), .a(a), .b(b), .o(fas_o) );
420 9 robfinch
fpDiv    #(WID) u11(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a), .b(b), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
421
fpMul    #(WID) u12(.clk(clk), .ce(pipe_ce),          .a(a), .b(b), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
422
/*
423
fpAddsub #(32) u10s(.clk(clk), .ce(pipe_ce), .rm(rm), .op(op[0]), .a(a[31:0]), .b(b[31:0]), .o(fass_o) );
424
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() );
425
fpMul    #(32) u12s(.clk(clk), .ce(pipe_ce),          .a(a[31:0]), .b(b[31:0]), .o(fmuls_o), .sign_exe(), .inf(), .underflow(mulUnders) );
426
*/
427 10 robfinch
always @*
428
case(op2)
429
`FLOAT:
430 9 robfinch
    case (fn2)
431
    `FMUL:      under = mulUnder;
432
    `FDIV:      under = divUnder;
433
    default: begin under = 0; unders = 0; end
434
        endcase
435 10 robfinch
`VECTOR:
436
    case (fn2)
437
    `VFMUL:    under = mulUnder;
438
    `VFDIV:    under = divUnder;
439
    default: begin under = 0; unders = 0; end
440
    endcase
441
default: begin under = 0; unders = 0; end
442
endcase
443 9 robfinch
 
444 10 robfinch
always @*
445
case(op2)
446
`FLOAT:
447 9 robfinch
    case(fn2)
448
    `FADD:      fres <= fas_o;
449
    `FSUB:      fres <= fas_o;
450
    `FMUL:      fres <= fmul_o;
451
    `FDIV:      fres <= fdiv_o;
452
    default:    begin fres <= fas_o; fress <= fass_o; end
453
    endcase
454 10 robfinch
`VECTOR:
455
    case(fn2)
456
    `VFADD:   fres <= fas_o;
457
    `VFSUB:   fres <= fas_o;
458
    `VFMUL:   fres <= fmul_o;
459
    `VFDIV:   fres <= fdiv_o;
460
    default:    begin fres <= fas_o; fress <= fass_o; end
461
    endcase
462
default:    begin fres <= fas_o; fress <= fass_o; end
463
endcase
464 9 robfinch
 
465
// pipeline stage
466
// one cycle latency
467
fpNormalize #(WID) fpn0(.clk(clk), .ce(pipe_ce), .under(under), .i(fres), .o(fpn_o) );
468
//fpNormalize #(32) fpns(.clk(clk), .ce(pipe_ce), .under(unders), .i(fress), .o(fpns_o) );
469
 
470
// pipeline stage
471
// one cycle latency
472 10 robfinch
fpRoundReg #(WID) fpr0(.clk(clk), .ce(pipe_ce), .rm(rmd4), .i(fpn_o), .o(fpu_o) );
473 9 robfinch
//fpRoundReg #(32) fprs(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpns_o), .o(fpus_o) );
474
 
475
wire so = (isNan?nso:fpu_o[WID-1]);
476
            //single ? (isNans?nsos:fpus_o[31]): (isNan?nso:fpu_o[63]);
477
 
478
//fix: status should be registered
479
assign status = {
480
        rm,
481
        inexe,
482
        dbzxe,
483
        underxe,
484
        overxe,
485
        invopxe,
486
        nsfp,
487
 
488
        fractie,
489
        raz,
490
        1'b0,
491
        so & !zero,
492
        !so & !zero,
493
        zero,
494
        inf,
495
 
496
        swtx,
497
        inex,
498
        dbzx,
499
        underx,
500
        overx,
501
        giopx,
502
        gx,
503
        sx,
504
 
505 10 robfinch
        1'b0,  // cvtx
506
        1'b0,  // sqrtx
507
        fcmp & nanx,
508
        infzero,
509
        zerozero,
510
        infdiv,
511
        subinf,
512
        isNan
513 9 robfinch
        };
514
 
515
assign o = (!fstat) ?
516 10 robfinch
    (frm|fcx|fdx|fex) ? (a|imm) :
517 9 robfinch
    zl_op ? zlq_o :
518
    loo_op ? looq_o :
519
    {so,fpu_o[MSB-1:0]} : 'bz;
520
assign zero = fpu_o[MSB-1:0]==0;
521
 
522
wire [7:0] maxdivcnt;
523
generate begin
524
if (WID==128) begin
525
    assign inf = &fpu_o[126:112] && fpu_o[111:0]==0;
526
    assign subinf       = fpu_o[126:0]==`QSUBINFQ;
527
    assign infdiv       = fpu_o[126:0]==`QINFDIVQ;
528
    assign zerozero = fpu_o[126:0]==`QZEROZEROQ;
529
    assign infzero      = fpu_o[126:0]==`QINFZEROQ;
530
    assign maxdivcnt = 8'd250;
531
end
532
else if (WID==80) begin
533
    assign inf = &fpu_o[78:64] && fpu_o[63:0]==0;
534
    assign subinf       = fpu_o[78:0]==`QSUBINFDX;
535
    assign infdiv       = fpu_o[78:0]==`QINFDIVDX;
536
    assign zerozero = fpu_o[78:0]==`QZEROZERODX;
537
    assign infzero      = fpu_o[78:0]==`QINFZERODX;
538
    assign maxdivcnt = 8'd136;
539
end
540
else if (WID==64) begin
541
    assign inf      = &fpu_o[62:52] && fpu_o[51:0]==0;
542
    assign subinf   = fpu_o[62:0]==`QSUBINFD;
543
    assign infdiv   = fpu_o[62:0]==`QINFDIVD;
544
    assign zerozero = fpu_o[62:0]==`QZEROZEROD;
545
    assign infzero  = fpu_o[62:0]==`QINFZEROD;
546
    assign maxdivcnt = 8'd112;
547
end
548
else if (WID==32) begin
549
    assign inf      = &fpu_o[30:23] && fpu_o[22:0]==0;
550
    assign subinf   = fpu_o[30:0]==`QSUBINFS;
551
    assign infdiv   = fpu_o[30:0]==`QINFDIVS;
552
    assign zerozero = fpu_o[30:0]==`QZEROZEROS;
553
    assign infzero  = fpu_o[30:0]==`QINFZEROS;
554
    assign maxdivcnt = 8'd54;
555
end
556
end
557
endgenerate
558
 
559
assign exception = gx;
560
 
561
// Generate a done signal. Latency varys depending on the instruction.
562
always @(posedge clk)
563
begin
564
    if (rst)
565
        fpcnt <= 8'h00;
566
    else begin
567
    if (ld)
568
        case(ir[5:0])
569
        `FLOAT:
570
            begin
571 10 robfinch
                case(func6b)
572
                `FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,
573
                `FCVTSD,`FCVTSQ,`FCVTDS:  begin fpcnt <= 8'd0; end
574
                `FTOI:  begin fpcnt <= 8'd1; end
575
                `ITOF:  begin fpcnt <= 8'd1; end
576 9 robfinch
                `FCMP:  begin fpcnt <= 8'd0; end
577
                `FADD:  begin fpcnt <= 8'd8; end
578
                `FSUB:  begin fpcnt <= 8'd8; end
579
                `FMUL:  begin fpcnt <= 8'd10; end
580
                `FDIV:  begin fpcnt <= maxdivcnt; end
581
                default:    fpcnt <= 8'h00;
582
                endcase
583
            end
584 10 robfinch
        `VECTOR:
585
            case(func6b)
586
            `VFNEG:  begin fpcnt <= 8'd0; end
587
            `VFADD:  begin fpcnt <= 8'd8; end
588
            `VFSUB:  begin fpcnt <= 8'd8; end
589
            `VFSxx:  begin fpcnt <= 8'd0; end
590
            `VFMUL:  begin fpcnt <= 8'd10; end
591
            `VFDIV:  begin fpcnt <= maxdivcnt; end
592
            `VFTOI:  begin fpcnt <= 8'd1; end
593
            `VITOF:  begin fpcnt <= 8'd1; end
594
            default:    fpcnt <= 8'h00;
595
            endcase
596 9 robfinch
        default:    fpcnt <= 8'h00;
597
        endcase
598
    else if (!done)
599
        fpcnt <= fpcnt - 1;
600
    end
601
end
602
endmodule
603
 

powered by: WebSVN 2.1.0

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