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

Subversion Repositories ft816float

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

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

Line No. Rev Author Line
1 9 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2006-2016  Robert Finch, Waterloo
4
//    \  __ /    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
`define FLOAT   6'h36
73
`define FMOV    6'h00
74
`define FTOI    6'h02
75
`define ITOF    6'h03
76
`define FNEG    6'h04
77
`define FABS    6'h05
78
`define FSIGN   6'h06
79
`define FMAN    6'h07
80
`define FNABS   6'h08
81
`define FCVTSQ  6'h0B
82
`define FSTAT   6'h0C
83
`define FTX     6'h10
84
`define FCX     6'h11
85
`define FEX     6'h12
86
`define FDX     6'h13
87
`define FRM     6'h14
88
 
89
`define FCMP    3'h1
90
`define FADD    3'h4
91
`define FSUB    3'h5
92
`define FMUL    3'h6
93
`define FDIV    3'h7
94
 
95
`define QINFOS          23'h7FC000              // info
96
`define QSUBINFS        31'h7FC00001    // - infinity - infinity
97
`define QINFDIVS        31'h7FC00002    // - infinity / infinity
98
`define QZEROZEROS      31'h7FC00003    // - zero / zero
99
`define QINFZEROS       31'h7FC00004    // - infinity X zero
100
 
101
`define QINFOD          52'hFF80000000000               // info
102
`define QSUBINFD        63'h7FF0000000000001    // - infinity - infinity
103
`define QINFDIVD        63'h7FF0000000000002    // - infinity / infinity
104
`define QZEROZEROD  63'h7FF0000000000003        // - zero / zero
105
`define QINFZEROD       63'h7FF0000000000004    // - infinity X zero
106
 
107
`define QINFODX         64'hFF800000_00000000           // info
108
`define QSUBINFDX       79'h7FFF000000_0000000001       // - infinity - infinity
109
`define QINFDIVDX       79'h7FFF000000_0000000002       // - infinity / infinity
110
`define QZEROZERODX 79'h7FFF000000_0000000003   // - zero / zero
111
`define QINFZERODX      79'h7FFF000000_0000000004       // - infinity X zero
112
 
113
`define QINFOQ          112'hFF800000_0000000000_0000000000             // info
114
`define QSUBINFQ        127'h7F_FF00000000_0000000000_0000000001        // - infinity - infinity
115
`define QINFDIVQ        127'h7F_FF00000000_0000000000_0000000002        // - infinity / infinity
116
`define QZEROZEROQ  127'h7F_FF00000000_0000000000_0000000003    // - zero / zero
117
`define QINFZEROQ       127'h7F_FF00000000_0000000000_0000000004        // - infinity X zero
118
 
119
module fpUnit(rst, clk, ce, ir, ld, a, b, imm, o, status, exception, done);
120
 
121
parameter WID = 128;
122
localparam MSB = WID-1;
123
localparam EMSB = WID==128 ? 14 :
124
                  WID==96 ? 14 :
125
                  WID==80 ? 14 :
126
                  WID==64 ? 10 :
127
                                  WID==52 ? 10 :
128
                                  WID==48 ? 10 :
129
                                  WID==44 ? 10 :
130
                                  WID==42 ? 10 :
131
                                  WID==40 ?  9 :
132
                                  WID==32 ?  7 :
133
                                  WID==24 ?  6 : 4;
134
localparam FMSB = WID==128 ? 111 :
135
                  WID==96 ? 79 :
136
                  WID==80 ? 63 :
137
                  WID==64 ? 51 :
138
                                  WID==52 ? 39 :
139
                                  WID==48 ? 35 :
140
                                  WID==44 ? 31 :
141
                                  WID==42 ? 29 :
142
                                  WID==40 ? 28 :
143
                                  WID==32 ? 22 :
144
                                  WID==24 ? 15 : 9;
145
localparam EMSBS = 7;
146
localparam FMSBS = 22;
147
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
148
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
149
localparam FXS = (FMSBS+2)*2-1; // the MSB of the expanded fraction
150
localparam EXS = FXS + 1 + EMSBS + 1 + 1 - 1;
151
 
152
input rst;
153
input clk;
154
input ce;
155
input [31:0] ir;
156
input ld;
157
input [MSB:0] a;
158
input [MSB:0] b;
159
input [5:0] imm;
160
output tri [MSB:0] o;
161
output [31:0] status;
162
output exception;
163
output done;
164
 
165
 
166
reg [7:0] fpcnt;
167
assign done = fpcnt==8'h00;
168
 
169
//------------------------------------------------------------
170
// constants
171
wire infXpq = {15{1'b1}};
172
wire infXp = {11{1'b1}};        // value for infinite exponent / nan
173
wire infXps = {8{1'b1}};
174
 
175
// Variables
176
wire divByZero;                 // attempt to divide by zero
177
wire inf;                               // result is infinite (+ or -)
178
wire zero;                              // result is zero (+ or -)
179
wire ns;                // nan sign
180
wire nss;
181
wire nso;
182
wire nsos;
183
wire isNan,isNans;
184
wire nanx,nanxs;
185
 
186
// Decode fp operation
187
wire [5:0] op = ir[5:0];
188
wire [5:0] func6b = ir[17:12];
189
wire [1:0] prec = ir[28:27];
190
wire [2:0] func3 = ir[31:29];
191
wire fstat      = {op,func3,func6b} == {`FLOAT,3'b000,`FSTAT};  // get status
192
wire fdiv       = {op,func3} == {`FLOAT,`FDIV};
193
wire ftx        = {op,func3,func6b} == {`FLOAT,3'b000,`FTX};            // trigger exception
194
wire fcx        = {op,func3,func6b} == {`FLOAT,3'b000,`FCX};            // clear exception
195
wire fex        = {op,func3,func6b} == {`FLOAT,3'b000,`FEX};            // enable exception
196
wire fdx        = {op,func3,func6b} == {`FLOAT,3'b000,`FDX};            // disable exception
197
wire fcmp       = {op,func3} == {`FLOAT,`FCMP};
198
wire frm        = {op,func3,func6b} == {`FLOAT,3'b000,`FRM};  // set rounding mode
199
 
200
wire zl_op =  (op==`FLOAT && ((func3==3'b000 &&
201
                    (func6b==`FABS || func6b==`FNABS || func6b==`FMOV || func6b==`FNEG || func6b==`FSIGN || func6b==`FMAN || func6b==`FCVTSQ)) ||
202
                    func3==`FCMP));
203
wire loo_op = (op==`FLOAT && func3==3'b000 && (func6b==`ITOF || func6b==`FTOI));
204
wire loo_done;
205
 
206
wire subinf;
207
wire zerozero;
208
wire infzero;
209
wire infdiv;
210
 
211
// floating point control and status
212
reg [2:0] rm;    // rounding mode
213
reg inexe;              // inexact exception enable
214
reg dbzxe;              // divide by zero exception enable
215
reg underxe;    // underflow exception enable
216
reg overxe;             // overflow exception enable
217
reg invopxe;    // invalid operation exception enable
218
 
219
reg nsfp;               // non-standard floating point indicator
220
 
221
reg fractie;    // fraction inexact
222
reg raz;                // rounded away from zero
223
 
224
reg inex;               // inexact exception
225
reg dbzx;               // divide by zero exception
226
reg underx;             // underflow exception
227
reg overx;              // overflow exception
228
reg giopx;              // global invalid operation exception
229
reg sx;                 // summary exception
230
 
231
reg swtx;               // software triggered exception indicator
232
 
233
wire gx = swtx|inex|dbzx|underx|overx|giopx;    // global exception indicator
234
 
235
// breakdown of invalid operation exceptions
236
reg cvtx;               // conversion exception
237
reg sqrtx;              // squareroot exception
238
reg NaNCmpx;    // NaN comparison exception
239
reg infzerox;   // multiply infinity by zero
240
reg zerozerox;  // division of zero by zero
241
reg infdivx;    // division of infinities
242
reg subinfx;    // subtraction of infinities
243
reg snanx;              // signalling nan
244
 
245
wire divDone;
246
wire pipe_ce = ce;// & divDone; // divide must be done in order for pipe to clock
247
wire precmatch = WID==32 ? ir[28:27]==2'b00 :
248
                 WID==64 ? ir[28:27]==2'b01 : 1;
249
                 /*
250
                 WID==80 ? ir[28:27]==2'b10 :
251
                 ir[28:27]==2'b11;
252
                 */
253
 
254
always @(posedge clk)
255
        // reset: disable and clear all exceptions and status
256
        if (rst) begin
257
                rm <= 2'b0;                     // round nearest even - default rounding mode
258
                inex <= 1'b0;
259
                dbzx <= 1'b0;
260
                underx <= 1'b0;
261
                overx <= 1'b0;
262
                giopx <= 1'b0;
263
                swtx <= 1'b0;
264
                sx <= 1'b0;
265
                NaNCmpx <= 1'b0;
266
 
267
                inexe <= 1'b0;
268
                dbzxe <= 1'b0;
269
                underxe <= 1'b0;
270
                overxe <= 1'b0;
271
                invopxe <= 1'b0;
272
 
273
                nsfp <= 1'b0;
274
 
275
                infzerox  <= 1'b0;
276
                zerozerox <= 1'b0;
277
                subinfx   <= 1'b0;
278
                infdivx   <= 1'b0;
279
 
280
        cvtx <= 1'b0;
281
        sqrtx <= 1'b0;
282
        raz <= 1'b0;
283
        fractie <= 1'b0;
284
        snanx <= 1'b0;
285
        end
286
        else if (pipe_ce) begin
287
                if (ftx && precmatch) begin
288
                        inex <= inex     | (a[4]|imm[4]);
289
                        dbzx <= dbzx     | (a[3]|imm[3]);
290
                        underx <= underx | (a[2]|imm[2]);
291
                        overx <= overx   | (a[1]|imm[1]);
292
                        giopx <= giopx   | (a[0]|imm[0]);
293
                        swtx <= 1'b1;
294
                        sx <= 1'b1;
295
                end
296
                else if (fcx && precmatch) begin
297
                        sx <= sx & !(a[5]|imm[5]);
298
                        inex <= inex     & !(a[4]|imm[4]);
299
                        dbzx <= dbzx     & !(a[3]|imm[3]);
300
                        underx <= underx & !(a[2]|imm[2]);
301
                        overx <= overx   & !(a[1]|imm[1]);
302
                        giopx <= giopx   & !(a[0]|imm[0]);
303
                        // clear exception type when global invalid operation is cleared
304
                        infdivx <= infdivx & !(a[0]|imm[0]);
305
                        zerozerox <= zerozerox & !(a[0]|imm[0]);
306
                        subinfx   <= subinfx   & !(a[0]|imm[0]);
307
                        infzerox  <= infzerox  & !(a[0]|imm[0]);
308
                        NaNCmpx   <= NaNCmpx   & !(a[0]|imm[0]);
309
                        dbzx <= dbzx & !(a[0]|imm[0]);
310
                        swtx <= 1'b1;
311
                end
312
                else if (fex && precmatch) begin
313
                        inexe <= inexe     | (a[4]|imm[4]);
314
                        dbzxe <= dbzxe     | (a[3]|imm[3]);
315
                        underxe <= underxe | (a[2]|imm[2]);
316
                        overxe <= overxe   | (a[1]|imm[1]);
317
                        invopxe <= invopxe | (a[0]|imm[0]);
318
                end
319
                else if (fdx && precmatch) begin
320
                        inexe <= inexe     & !(a[4]|imm[4]);
321
                        dbzxe <= dbzxe     & !(a[3]|imm[3]);
322
                        underxe <= underxe & !(a[2]|imm[2]);
323
                        overxe <= overxe   & !(a[1]|imm[1]);
324
                        invopxe <= invopxe & !(a[0]|imm[0]);
325
                end
326
                else if (frm && precmatch)
327
                        rm <= a[2:0]|imm[2:0];
328
 
329
                infzerox  <= infzerox  | (invopxe & infzero);
330
                zerozerox <= zerozerox | (invopxe & zerozero);
331
                subinfx   <= subinfx   | (invopxe & subinf);
332
                infdivx   <= infdivx   | (invopxe & infdiv);
333
                dbzx <= dbzx | (dbzxe & divByZero);
334
                NaNCmpx <= NaNCmpx | (invopxe & nanx & fcmp);   // must be a compare
335
                sx <= sx |
336
                                (invopxe & nanx & fcmp) |
337
                                (invopxe & (infzero|zerozero|subinf|infdiv)) |
338
                                (dbzxe & divByZero);
339
           snanx <= isNan;
340
        end
341
 
342
// Decompose operands into sign,exponent,mantissa
343
wire sa, sb, sas, sbs;
344
wire [FMSB:0] ma, mb;
345
wire [22:0] mas, mbs;
346
 
347
wire aInf, bInf, aInfs, bInfs;
348
wire aNan, bNan, aNans, bNans;
349
wire az, bz, azs, bzs;
350
wire [2:0] rmd4; // 1st stage delayed
351
wire [7:0] op1, op2;
352
wire [5:0] fn1;
353
wire [2:0] fn2;
354
 
355
wire [MSB:0] zld_o,lood_o;
356
wire [31:0] zls_o,loos_o;
357
wire [127:0] zlq_o;
358
fpZLUnit #(WID) u6 (.ir(ir), .a(a), .b(b), .o(zlq_o), .nanx(nanx) );
359
fpLOOUnit #(WID) u7 (.clk(clk), .ce(pipe_ce), .ir(ir), .a(a), .o(looq_o), .done(looq_done) );
360
//fpLOOUnit #(32) u7s (.clk(clk), .ce(pipe_ce), .rm(rm), .op(op), .fn(fn), .a(a[31:0]), .o(loos_o), .done() );
361
assign zl_o = zlq_o;
362
assign loo_o = looq_o;
363
 
364
fp_decomp #(WID) u1 (.i(a), .sgn(sa), .man(ma), .vz(az), .inf(aInf), .nan(aNan) );
365
fp_decomp #(WID) u2 (.i(b), .sgn(sb), .man(mb), .vz(bz), .inf(bInf), .nan(bNan) );
366
//fp_decomp #(32) u1s (.i(a[31:0]), .sgn(sas), .man(mas), .vz(azs), .inf(aInfs), .nan(aNans) );
367
//fp_decomp #(32) u2s (.i(b[31:0]), .sgn(sbs), .man(mbs), .vz(bzs), .inf(bInfs), .nan(bNans) );
368
 
369
wire [2:0] rmd = ir[26:24]==3'b111 ? rm : ir[26:24];
370
delay4 #(3) u3 (.clk(clk), .ce(pipe_ce), .i(rmd), .o(rmd4) );
371
delay1 #(6) u4 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op1) );
372
delay2 #(6) u5 (.clk(clk), .ce(pipe_ce), .i(func6b), .o(op2) );
373
delay1 #(3) u5a (.clk(clk), .ce(pipe_ce), .i(func3), .o(fn1) );
374
delay2 #(3) u5b (.clk(clk), .ce(pipe_ce), .i(func3), .o(fn2) );
375
 
376
delay5 delay5_3(.clk(clk), .ce(pipe_ce), .i((bz & !aNan & fdiv)|(bzs & !aNans & fdivs)), .o(divByZero) );
377
 
378
// Compute NaN output sign
379
wire aob_nan = aNan|bNan;       // one of the operands is a nan
380
wire bothNan = aNan&bNan;       // both of the operands are nans
381
//wire aob_nans = aNans|bNans;  // one of the operands is a nan
382
//wire bothNans = aNans&bNans;  // both of the operands are nans
383
 
384
assign ns = bothNan ?
385
                                (ma==mb ? sa & sb : ma < mb ? sb : sa) :
386
                                aNan ? sa : sb;
387
//assign nss = bothNans ?
388
//                                 (mas==mbs ? sas & sbs : mas < mbs ? sbs : sas) :
389
//                                  aNans ? sas : sbs;
390
 
391
delay5 u8(.clk(clk), .ce(ce), .i(ns), .o(nso) );
392
delay5 u9(.clk(clk), .ce(ce), .i(aob_nan), .o(isNan) );
393
//delay5 u8s(.clk(clk), .ce(ce), .i(nss), .o(nsos) );
394
//delay5 u9s(.clk(clk), .ce(ce), .i(aob_nans), .o(isNans) );
395
 
396
wire [MSB:0] fpu_o;
397
wire [MSB+3:0] fpn_o;
398
wire [EX:0] fdiv_o;
399
wire [EX:0] fmul_o;
400
wire [EX:0] fas_o;
401
reg  [EX:0] fres;
402
wire [31:0] fpus_o;
403
wire [31+3:0] fpns_o;
404
wire [EXS:0] fdivs_o;
405
wire [EXS:0] fmuls_o;
406
wire [EXS:0] fass_o;
407
reg  [EXS:0] fress;
408
wire divUnder,divUnders;
409
wire mulUnder,mulUnders;
410
reg under,unders;
411
 
412
fpAddsub #(WID) u10(.clk(clk), .ce(pipe_ce), .rm(rmd), .op(func3[0]), .a(a), .b(b), .o(fas_o) );
413
fpDiv    #(WID) u11(.clk(clk), .ce(pipe_ce), .ld(ld), .a(a), .b(b), .o(fdiv_o), .sign_exe(), .underflow(divUnder), .done(divDone) );
414
fpMul    #(WID) u12(.clk(clk), .ce(pipe_ce),          .a(a), .b(b), .o(fmul_o), .sign_exe(), .inf(), .underflow(mulUnder) );
415
/*
416
fpAddsub #(32) u10s(.clk(clk), .ce(pipe_ce), .rm(rm), .op(op[0]), .a(a[31:0]), .b(b[31:0]), .o(fass_o) );
417
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() );
418
fpMul    #(32) u12s(.clk(clk), .ce(pipe_ce),          .a(a[31:0]), .b(b[31:0]), .o(fmuls_o), .sign_exe(), .inf(), .underflow(mulUnders) );
419
*/
420
always @(fn2,mulUnder,divUnder,mulUnders,divUnders)
421
    case (fn2)
422
    `FMUL:      under = mulUnder;
423
    `FDIV:      under = divUnder;
424
    default: begin under = 0; unders = 0; end
425
        endcase
426
 
427
always @(fn2,fas_o,fmul_o,fdiv_o,fass_o,fmuls_o,fdivs_o)
428
    case(fn2)
429
    `FADD:      fres <= fas_o;
430
    `FSUB:      fres <= fas_o;
431
    `FMUL:      fres <= fmul_o;
432
    `FDIV:      fres <= fdiv_o;
433
    default:    begin fres <= fas_o; fress <= fass_o; end
434
    endcase
435
 
436
// pipeline stage
437
// one cycle latency
438
fpNormalize #(WID) fpn0(.clk(clk), .ce(pipe_ce), .under(under), .i(fres), .o(fpn_o) );
439
//fpNormalize #(32) fpns(.clk(clk), .ce(pipe_ce), .under(unders), .i(fress), .o(fpns_o) );
440
 
441
// pipeline stage
442
// one cycle latency
443
fpRoundReg #(WID) fpr0(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpn_o), .o(fpu_o) );
444
//fpRoundReg #(32) fprs(.clk(clk), .ce(pipe_ce), .rm(rm4), .i(fpns_o), .o(fpus_o) );
445
 
446
wire so = (isNan?nso:fpu_o[WID-1]);
447
            //single ? (isNans?nsos:fpus_o[31]): (isNan?nso:fpu_o[63]);
448
 
449
//fix: status should be registered
450
assign status = {
451
        rm,
452
        inexe,
453
        dbzxe,
454
        underxe,
455
        overxe,
456
        invopxe,
457
        nsfp,
458
 
459
        fractie,
460
        raz,
461
        1'b0,
462
        so & !zero,
463
        !so & !zero,
464
        zero,
465
        inf,
466
 
467
        swtx,
468
        inex,
469
        dbzx,
470
        underx,
471
        overx,
472
        giopx,
473
        gx,
474
        sx,
475
 
476
        cvtx,
477
        sqrtx,
478
        NaNCmpx,
479
        infzerox,
480
        zerozerox,
481
        infdivx,
482
        subinfx,
483
        snanx
484
        };
485
 
486
assign o = (!fstat) ?
487
    zl_op ? zlq_o :
488
    loo_op ? looq_o :
489
    {so,fpu_o[MSB-1:0]} : 'bz;
490
assign zero = fpu_o[MSB-1:0]==0;
491
 
492
wire [7:0] maxdivcnt;
493
generate begin
494
if (WID==128) begin
495
    assign inf = &fpu_o[126:112] && fpu_o[111:0]==0;
496
    assign subinf       = fpu_o[126:0]==`QSUBINFQ;
497
    assign infdiv       = fpu_o[126:0]==`QINFDIVQ;
498
    assign zerozero = fpu_o[126:0]==`QZEROZEROQ;
499
    assign infzero      = fpu_o[126:0]==`QINFZEROQ;
500
    assign maxdivcnt = 8'd250;
501
end
502
else if (WID==80) begin
503
    assign inf = &fpu_o[78:64] && fpu_o[63:0]==0;
504
    assign subinf       = fpu_o[78:0]==`QSUBINFDX;
505
    assign infdiv       = fpu_o[78:0]==`QINFDIVDX;
506
    assign zerozero = fpu_o[78:0]==`QZEROZERODX;
507
    assign infzero      = fpu_o[78:0]==`QINFZERODX;
508
    assign maxdivcnt = 8'd136;
509
end
510
else if (WID==64) begin
511
    assign inf      = &fpu_o[62:52] && fpu_o[51:0]==0;
512
    assign subinf   = fpu_o[62:0]==`QSUBINFD;
513
    assign infdiv   = fpu_o[62:0]==`QINFDIVD;
514
    assign zerozero = fpu_o[62:0]==`QZEROZEROD;
515
    assign infzero  = fpu_o[62:0]==`QINFZEROD;
516
    assign maxdivcnt = 8'd112;
517
end
518
else if (WID==32) begin
519
    assign inf      = &fpu_o[30:23] && fpu_o[22:0]==0;
520
    assign subinf   = fpu_o[30:0]==`QSUBINFS;
521
    assign infdiv   = fpu_o[30:0]==`QINFDIVS;
522
    assign zerozero = fpu_o[30:0]==`QZEROZEROS;
523
    assign infzero  = fpu_o[30:0]==`QINFZEROS;
524
    assign maxdivcnt = 8'd54;
525
end
526
end
527
endgenerate
528
 
529
assign exception = gx;
530
 
531
// Generate a done signal. Latency varys depending on the instruction.
532
always @(posedge clk)
533
begin
534
    if (rst)
535
        fpcnt <= 8'h00;
536
    else begin
537
    if (ld)
538
        case(ir[5:0])
539
        `FLOAT:
540
            begin
541
                case(ir[31:29])
542
                3'd0:
543
                    case(ir[23:18])
544
                    `FABS,`FNABS,`FNEG,`FMAN,`FMOV,`FSIGN,`FCVTSQ:  begin fpcnt <= 8'd0; end
545
                    `FTOI:  begin fpcnt <= 8'd1; end
546
                    `ITOF:  begin fpcnt <= 8'd1; end
547
                    default:    fpcnt <= 8'h00;
548
                    endcase
549
                `FCMP:  begin fpcnt <= 8'd0; end
550
                `FADD:  begin fpcnt <= 8'd8; end
551
                `FSUB:  begin fpcnt <= 8'd8; end
552
                `FMUL:  begin fpcnt <= 8'd10; end
553
                `FDIV:  begin fpcnt <= maxdivcnt; end
554
                default:    fpcnt <= 8'h00;
555
                endcase
556
            end
557
        default:    fpcnt <= 8'h00;
558
        endcase
559
    else if (!done)
560
        fpcnt <= fpcnt - 1;
561
    end
562
end
563
endmodule
564
 

powered by: WebSVN 2.1.0

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