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

Subversion Repositories fpu

[/] [fpu/] [trunk/] [verilog/] [post_norm.v] - Blame information for rev 5

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

Line No. Rev Author Line
1 2 rudi
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Post Norm                                                  ////
4
////  Floating Point Post Normalisation Unit                     ////
5
////                                                             ////
6
////  Author: Rudolf Usselmann                                   ////
7
////          rudi@asics.ws                                      ////
8
////                                                             ////
9
/////////////////////////////////////////////////////////////////////
10
////                                                             ////
11
//// Copyright (C) 2000 Rudolf Usselmann                         ////
12
////                    rudi@asics.ws                            ////
13
////                                                             ////
14
//// This source file may be used and distributed without        ////
15
//// restriction provided that this copyright statement is not   ////
16
//// removed from the file and that any derivative work contains ////
17
//// the original copyright notice and the associated disclaimer.////
18
////                                                             ////
19
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
20
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
21
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
22
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
23
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
24
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
25
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
26
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
27
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
28
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
29
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
30
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
31
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
32
////                                                             ////
33
/////////////////////////////////////////////////////////////////////
34
 
35
 
36
`timescale 1ns / 100ps
37
 
38 5 rudi
module post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf,
39 2 rudi
                opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out,
40 5 rudi
                ine, overflow, underflow, f2i_out_sign);
41 2 rudi
input           clk;
42
input   [2:0]    fpu_op;
43 5 rudi
input           opas;
44 2 rudi
input           sign;
45
input   [1:0]    rmode;
46
input   [47:0]   fract_in;
47
input   [1:0]    exp_ovf;
48
input   [7:0]    exp_in;
49
input           opa_dn, opb_dn;
50
input           rem_00;
51
input   [4:0]    div_opa_ldz;
52
input           output_zero;
53
output  [30:0]   out;
54
output          ine;
55
output          overflow, underflow;
56 5 rudi
output          f2i_out_sign;
57 2 rudi
 
58
////////////////////////////////////////////////////////////////////////
59
//
60
// Local Wires and registers
61
//
62
 
63
wire    [22:0]   fract_out;
64
wire    [7:0]    exp_out;
65
wire    [30:0]   out;
66
wire            exp_out1_co, overflow, underflow;
67
wire    [22:0]   fract_out_final;
68
reg     [22:0]   fract_out_rnd;
69
wire    [8:0]    exp_next_mi;
70
wire            dn;
71
wire            exp_rnd_adj;
72
wire    [7:0]    exp_out_final;
73
reg     [7:0]    exp_out_rnd;
74
wire            op_dn = opa_dn | opb_dn;
75
wire            op_mul = fpu_op[2:0]==3'b010;
76
wire            op_div = fpu_op[2:0]==3'b011;
77 5 rudi
wire            op_i2f = fpu_op[2:0]==3'b100;
78
wire            op_f2i = fpu_op[2:0]==3'b101;
79 2 rudi
reg     [5:0]    fi_ldz;
80
 
81
wire            g, r, s;
82
wire            round, round2, round2a, round2_fasu, round2_fmul;
83
wire    [7:0]    exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a;
84
wire    [22:0]   fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a;
85
wire            exp_rnd_adj0, exp_rnd_adj2a;
86
wire            r_sign;
87
wire            ovf0, ovf1;
88
wire    [23:0]   fract_out_pl1;
89
wire    [7:0]    exp_out_pl1, exp_out_mi1;
90
wire            exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff;
91
wire            exp_out_final_ff, fract_out_7fffff;
92
wire    [24:0]   fract_trunc;
93
wire    [7:0]    exp_out1;
94
wire            grs_sel;
95
wire            fract_out_00, fract_in_00;
96
wire            shft_co;
97
wire    [8:0]    exp_in_pl1, exp_in_mi1;
98
wire    [47:0]   fract_in_shftr;
99
wire    [47:0]   fract_in_shftl;
100
 
101
wire    [7:0]    exp_div;
102
wire    [7:0]    shft2;
103
wire    [7:0]    exp_out1_mi1;
104
wire            div_dn;
105
wire            div_nr;
106
wire            grs_sel_div;
107
 
108
wire            div_inf;
109
wire    [6:0]    fi_ldz_2a;
110
wire    [7:0]    fi_ldz_2;
111
wire    [7:0]    div_shft1, div_shft2, div_shft3, div_shft4;
112
wire            div_shft1_co;
113
wire    [8:0]    div_exp1;
114
wire    [7:0]    div_exp2, div_exp3;
115
wire            left_right, lr_mul, lr_div;
116
wire    [7:0]    shift_right, shftr_mul, shftr_div;
117
wire    [7:0]    shift_left,  shftl_mul, shftl_div;
118
wire    [7:0]    fasu_shift;
119
wire    [7:0]    exp_fix_div;
120
 
121
wire    [7:0]    exp_fix_diva, exp_fix_divb;
122
wire    [5:0]    fi_ldz_mi1;
123
wire    [5:0]    fi_ldz_mi22;
124
wire            exp_zero;
125
wire    [6:0]    ldz_all;
126
wire    [7:0]    ldz_dif;
127
 
128 5 rudi
wire    [8:0]    div_scht1a;
129
wire    [7:0]    f2i_shft;
130
wire    [55:0]   exp_f2i_1;
131
wire            f2i_zero, f2i_max;
132
wire    [7:0]    f2i_emin;
133
wire    [7:0]    conv_shft;
134
wire    [7:0]    exp_i2f, exp_f2i, conv_exp;
135
wire            round2_f2i;
136
 
137 2 rudi
////////////////////////////////////////////////////////////////////////
138
//
139
// Normalize and Round Logic
140
//
141
 
142
// ---------------------------------------------------------------------
143
// Count Leading zeros in fraction
144
 
145
always @(fract_in)
146
   casex(fract_in)      // synopsys full_case parallel_case
147
        48'b1???????????????????????????????????????????????: fi_ldz =  1;
148
        48'b01??????????????????????????????????????????????: fi_ldz =  2;
149
        48'b001?????????????????????????????????????????????: fi_ldz =  3;
150
        48'b0001????????????????????????????????????????????: fi_ldz =  4;
151
        48'b00001???????????????????????????????????????????: fi_ldz =  5;
152
        48'b000001??????????????????????????????????????????: fi_ldz =  6;
153
        48'b0000001?????????????????????????????????????????: fi_ldz =  7;
154
        48'b00000001????????????????????????????????????????: fi_ldz =  8;
155
        48'b000000001???????????????????????????????????????: fi_ldz =  9;
156
        48'b0000000001??????????????????????????????????????: fi_ldz =  10;
157
        48'b00000000001?????????????????????????????????????: fi_ldz =  11;
158
        48'b000000000001????????????????????????????????????: fi_ldz =  12;
159
        48'b0000000000001???????????????????????????????????: fi_ldz =  13;
160
        48'b00000000000001??????????????????????????????????: fi_ldz =  14;
161
        48'b000000000000001?????????????????????????????????: fi_ldz =  15;
162
        48'b0000000000000001????????????????????????????????: fi_ldz =  16;
163
        48'b00000000000000001???????????????????????????????: fi_ldz =  17;
164
        48'b000000000000000001??????????????????????????????: fi_ldz =  18;
165
        48'b0000000000000000001?????????????????????????????: fi_ldz =  19;
166
        48'b00000000000000000001????????????????????????????: fi_ldz =  20;
167
        48'b000000000000000000001???????????????????????????: fi_ldz =  21;
168
        48'b0000000000000000000001??????????????????????????: fi_ldz =  22;
169
        48'b00000000000000000000001?????????????????????????: fi_ldz =  23;
170
        48'b000000000000000000000001????????????????????????: fi_ldz =  24;
171
        48'b0000000000000000000000001???????????????????????: fi_ldz =  25;
172
        48'b00000000000000000000000001??????????????????????: fi_ldz =  26;
173
        48'b000000000000000000000000001?????????????????????: fi_ldz =  27;
174
        48'b0000000000000000000000000001????????????????????: fi_ldz =  28;
175
        48'b00000000000000000000000000001???????????????????: fi_ldz =  29;
176
        48'b000000000000000000000000000001??????????????????: fi_ldz =  30;
177
        48'b0000000000000000000000000000001?????????????????: fi_ldz =  31;
178
        48'b00000000000000000000000000000001????????????????: fi_ldz =  32;
179
        48'b000000000000000000000000000000001???????????????: fi_ldz =  33;
180
        48'b0000000000000000000000000000000001??????????????: fi_ldz =  34;
181
        48'b00000000000000000000000000000000001?????????????: fi_ldz =  35;
182
        48'b000000000000000000000000000000000001????????????: fi_ldz =  36;
183
        48'b0000000000000000000000000000000000001???????????: fi_ldz =  37;
184
        48'b00000000000000000000000000000000000001??????????: fi_ldz =  38;
185
        48'b000000000000000000000000000000000000001?????????: fi_ldz =  39;
186
        48'b0000000000000000000000000000000000000001????????: fi_ldz =  40;
187
        48'b00000000000000000000000000000000000000001???????: fi_ldz =  41;
188
        48'b000000000000000000000000000000000000000001??????: fi_ldz =  42;
189
        48'b0000000000000000000000000000000000000000001?????: fi_ldz =  43;
190
        48'b00000000000000000000000000000000000000000001????: fi_ldz =  44;
191
        48'b000000000000000000000000000000000000000000001???: fi_ldz =  45;
192
        48'b0000000000000000000000000000000000000000000001??: fi_ldz =  46;
193
        48'b00000000000000000000000000000000000000000000001?: fi_ldz =  47;
194
        48'b00000000000000000000000000000000000000000000000?: fi_ldz =  48;
195
   endcase
196
 
197
 
198
// ---------------------------------------------------------------------
199
// Normalize
200
 
201
wire            exp_in_80;
202
wire            rmode_00, rmode_01, rmode_10, rmode_11;
203
 
204
// Misc common signals
205
assign exp_in_ff        = &exp_in;
206
assign exp_in_00        = !(|exp_in);
207
assign exp_in_80        = exp_in[7] & !(|exp_in[6:0]);
208
assign exp_out_ff       = &exp_out;
209
assign exp_out_00       = !(|exp_out);
210
assign exp_out_fe       = &exp_out[7:1] & !exp_out[0];
211
assign exp_out_final_ff = &exp_out_final;
212
 
213
assign fract_out_7fffff = &fract_out;
214
assign fract_out_00     = !(|fract_out);
215
assign fract_in_00      = !(|fract_in);
216
 
217
assign rmode_00 = (rmode==2'b00);
218
assign rmode_01 = (rmode==2'b01);
219
assign rmode_10 = (rmode==2'b10);
220
assign rmode_11 = (rmode==2'b11);
221
 
222
// Fasu Output will be denormalized ...
223
assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );
224
 
225
// ---------------------------------------------------------------------
226
// Fraction Normalization
227 5 rudi
parameter       f2i_emax = 8'h9d;
228 2 rudi
 
229 5 rudi
// Incremented fraction for rounding
230 2 rudi
assign fract_out_pl1 = fract_out + 1;
231
 
232 5 rudi
// Special Signals for f2i
233
assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;
234
assign f2i_zero = (!opas & (exp_in<f2i_emin)) | (opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));
235
assign f2i_max = (!opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);
236
 
237 2 rudi
// Claculate various shifting options
238
 
239
assign {shft_co,shftr_mul} = (!exp_ovf[1] & exp_in_00) ? {1'b0, exp_out} : exp_in_mi1 ;
240
assign {div_shft1_co, div_shft1} = exp_in_00 ? {1'b0, div_opa_ldz} : div_scht1a;
241
 
242
assign div_scht1a = exp_in-div_opa_ldz; // 9 bits - includes carry out
243
assign div_shft2  = exp_in+2;
244
assign div_shft3  = div_opa_ldz+exp_in;
245
assign div_shft4  = div_opa_ldz-exp_in;
246
 
247
assign div_dn    = op_dn & div_shft1_co;
248
assign div_nr    = op_dn & exp_ovf[1]  & !(|fract_in[46:23]) & (div_shft3>8'h16);
249
 
250 5 rudi
assign f2i_shft  = exp_in-8'h7d;
251 2 rudi
 
252
// Select shifting direction
253
assign left_right = op_div ? lr_div : op_mul ? lr_mul : 1;
254
 
255
assign lr_div =         (op_dn & !exp_ovf[1] & exp_ovf[0])     ? 1 :
256
                        (op_dn & exp_ovf[1])                   ? 0 :
257
                        (op_dn & div_shft1_co)                 ? 0 :
258
                        (op_dn & exp_out_00)                   ? 1 :
259
                        (!op_dn & exp_out_00 & !exp_ovf[1])    ? 1 :
260
                        exp_ovf[1]                             ? 0 :
261
                                                                 1;
262
assign lr_mul =         (shft_co | (!exp_ovf[1] & exp_in_00) |
263
                        (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ?     1 :
264
                        ( exp_ovf[1] | exp_in_00 ) ?                                    0 :
265
                                                                                        1;
266
 
267
// Select Left and Right shift value
268
assign fasu_shift  = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz};
269
assign shift_right = op_div ? shftr_div : shftr_mul;
270
 
271 5 rudi
assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};
272
 
273
assign shift_left  = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift;
274
 
275 2 rudi
assign shftl_mul =      (shft_co |
276
                        (!exp_ovf[1] & exp_in_00) |
277
                        (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz};
278
 
279
assign shftl_div =      ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0]))      ? div_shft1[7:0] :
280
                        (!op_dn & exp_out_00 & !exp_ovf[1])                     ? exp_in[7:0] :
281
                                                                                 {2'h0, fi_ldz};
282
assign shftr_div =      (op_dn & exp_ovf[1])                   ? div_shft3 :
283
                        (op_dn & div_shft1_co)                 ? div_shft4 :
284
                                                                 div_shft2;
285
// Do the actual shifting
286 5 rudi
assign fract_in_shftr   = (|shift_right[7:6])                      ? 0 : fract_in>>shift_right[5:0];
287
assign fract_in_shftl   = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<<shift_left[5:0];
288 2 rudi
 
289
// Chose final fraction output
290
assign {fract_out,fract_trunc} = left_right ? fract_in_shftl : fract_in_shftr;
291
 
292
// ---------------------------------------------------------------------
293
// Exponent Normalization
294
 
295
assign fi_ldz_mi1    = fi_ldz - 1;
296
assign fi_ldz_mi22   = fi_ldz - 22;
297
assign exp_out_pl1   = exp_out + 1;
298
assign exp_out_mi1   = exp_out - 1;
299
assign exp_in_pl1    = exp_in  + 1;     // 9 bits - includes carry out
300
assign exp_in_mi1    = exp_in  - 1;     // 9 bits - includes carry out
301
assign exp_out1_mi1  = exp_out1 - 1;
302
 
303
assign exp_next_mi  = exp_in_pl1 - fi_ldz_mi1;  // 9 bits - includes carry out
304 5 rudi
 
305 2 rudi
assign exp_fix_diva = exp_in - fi_ldz_mi22;
306
assign exp_fix_divb = exp_in - fi_ldz_mi1;
307
 
308
assign exp_zero  = (exp_ovf[1] & !exp_ovf[0] & op_mul & (!exp_rnd_adj2a | !rmode[1])) | (op_mul & exp_out1_co);
309
assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;
310
 
311 5 rudi
assign f2i_out_sign =  !opas ? ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 0 : opas) :
312
                               ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 1 : opas);
313
 
314
assign exp_i2f   = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz);
315
assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft;
316
assign exp_f2i   = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48];
317
assign conv_exp  = op_f2i ? exp_f2i : exp_i2f;
318
 
319
assign exp_out = op_div ? exp_div : (op_f2i | op_i2f) ? conv_exp : exp_zero ? 8'h0 : dn ? {6'h0, fract_in[47:46]} : exp_out1;
320
 
321 2 rudi
assign ldz_all   = div_opa_ldz + fi_ldz;
322
assign ldz_dif   = fi_ldz_2 - div_opa_ldz;
323
assign fi_ldz_2a = 6'd23 - fi_ldz;
324
assign fi_ldz_2  = {fi_ldz_2a[6], fi_ldz_2a[6:0]};
325 5 rudi
 
326 2 rudi
assign div_exp1  = exp_in_mi1 + fi_ldz_2;       // 9 bits - includes carry out
327 5 rudi
 
328 2 rudi
assign div_exp2  = exp_in_pl1 - ldz_all;
329
assign div_exp3  = exp_in + ldz_dif;
330
 
331
assign exp_div =(opa_dn & opb_dn)                                       ? div_exp3 :
332
                 opb_dn                                                 ? div_exp1[7:0] :
333
                (opa_dn & !( (exp_in<div_opa_ldz) | (div_exp2>9'hfe) )) ? div_exp2 :
334
                (opa_dn | (exp_in_00 & !exp_ovf[1]) )                   ? 0 :
335 5 rudi
                                                                          exp_out1_mi1;
336 2 rudi
 
337
assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f);
338
 
339
// ---------------------------------------------------------------------
340
// Round
341
 
342
// Extract rounding (GRS) bits
343
assign grs_sel_div = op_div & (exp_ovf[1] | div_dn | exp_out1_co | exp_out_00);
344
 
345
assign g = grs_sel_div ? fract_out[0]                   : fract_out[0];
346
assign r = grs_sel_div ? (fract_trunc[24] & !div_nr)    : fract_trunc[24];
347
assign s = grs_sel_div ? |fract_trunc[24:0]             : (|fract_trunc[23:0] | (fract_trunc[24] & op_div));
348
 
349
// Round to nearest even
350
assign round = (g & r) | (r & s) ;
351
assign {exp_rnd_adj0, fract_out_rnd0} = round ? fract_out_pl1 : {1'b0, fract_out};
352
assign exp_out_rnd0 =  exp_rnd_adj0 ? exp_out_pl1 : exp_out;
353 5 rudi
assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i;
354 2 rudi
 
355
// round to zero
356 5 rudi
assign fract_out_rnd1 = (exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out;
357
assign exp_fix_div    = (fi_ldz>22) ? exp_fix_diva : exp_fix_divb;
358 2 rudi
assign exp_out_rnd1   = (g & r & s & exp_in_ff) ? (op_div ? exp_fix_div : exp_next_mi[7:0]) :
359 5 rudi
                        (exp_out_ff & !op_f2i) ? exp_in : exp_out;
360 2 rudi
assign ovf1 = exp_out_ff & !dn;
361
 
362
// round to +inf (UP) and -inf (DOWN)
363
assign r_sign = sign;
364
 
365
assign round2a = !exp_out_fe | !fract_out_7fffff | (exp_out_fe & fract_out_7fffff);
366
assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] | (exp_out[7] & round2a));
367
 
368
assign round2_fmul = !r_sign &
369
                (
370
                        (exp_ovf[1] & !fract_in_00 &
371
                                ( ((!exp_out1_co | op_dn) & (r | s | (!rem_00 & op_div) )) | fract_out_00 | (!op_dn & !op_div))
372
                         ) |
373
                        (
374
                                (r | s | (!rem_00 & op_div)) & (
375
                                                (!exp_ovf[1] & (exp_in_80 | !exp_ovf[0])) | op_div |
376
                                                ( exp_ovf[1] & !exp_ovf[0] & exp_out1_co)
377
                                        )
378
                        )
379
                );
380
 
381 5 rudi
assign round2_f2i = rmode_10 & (( |fract_in[23:0] & !opas & (exp_in<8'h80 )) | (|fract_trunc));
382
assign round2 = (op_mul | op_div) ? round2_fmul : op_f2i ? round2_f2i : round2_fasu;
383 2 rudi
 
384
assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 : {1'b0, fract_out};
385 5 rudi
assign exp_out_rnd2a  = exp_rnd_adj2a ? ((exp_ovf[1] & op_mul) ? exp_out_mi1 : exp_out_pl1) : exp_out;
386 2 rudi
 
387 5 rudi
assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out_rnd2a;
388
assign exp_out_rnd2   = (r_sign & exp_out_ff & !op_f2i) ? 8'hfe      : exp_out_rnd2a;
389 2 rudi
 
390
 
391
// Choose rounding mode
392
always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2)
393
        case(rmode)     // synopsys full_case parallel_case
394
           0: exp_out_rnd = exp_out_rnd0;
395
           1: exp_out_rnd = exp_out_rnd1;
396
         2,3: exp_out_rnd = exp_out_rnd2;
397
        endcase
398
 
399
always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2)
400
        case(rmode)     // synopsys full_case parallel_case
401
           0: fract_out_rnd = fract_out_rnd0;
402
           1: fract_out_rnd = fract_out_rnd1;
403
         2,3: fract_out_rnd = fract_out_rnd2;
404
        endcase
405
 
406
// ---------------------------------------------------------------------
407
// Final Output Mux
408
// Fix Output for denormalized and special numbers
409
wire    max_num, inf_out;
410
 
411
assign  max_num =  ( !rmode_00 & (op_mul | op_div ) & (
412
                                                          ( exp_ovf[1] &  exp_ovf[0]) |
413
                                                          (!exp_ovf[1] & !exp_ovf[0] & exp_in_ff & (fi_ldz_2<24) & (exp_out!=8'hfe) )
414
                                                          )
415
                   ) |
416
 
417
                   ( op_div & (
418
                                   ( rmode_01 & ( div_inf |
419
                                                         (exp_out_ff & !exp_ovf[1] ) |
420
                                                         (exp_ovf[1] &  exp_ovf[0] )
421
                                                )
422
                                   ) |
423
 
424
                                   ( rmode[1] & !exp_ovf[1] & (
425
                                                                   ( exp_ovf[0] & exp_in_ff & r_sign & fract_in[47]
426
                                                                   ) |
427
 
428
                                                                   (  r_sign & (
429
                                                                                (fract_in[47] & div_inf) |
430
                                                                                (exp_in[7] & !exp_out_rnd[7] & !exp_in_80 & exp_out!=8'h7f ) |
431
                                                                                (exp_in[7] &  exp_out_rnd[7] & r_sign & exp_out_ff & op_dn &
432
                                                                                         div_exp1>9'h0fe )
433
                                                                                )
434
                                                                   ) |
435
 
436
                                                                   ( exp_in_00 & r_sign & (
437
                                                                                                div_inf |
438
                                                                                                (r_sign & exp_out_ff & fi_ldz_2<24)
439
                                                                                          )
440
                                                                   )
441
                                                               )
442
                                  )
443
                            )
444
                   );
445
 
446
 
447
assign inf_out = (rmode[1] & (op_mul | op_div) & !r_sign & (    (exp_in_ff & !op_div) |
448
                                                                (exp_ovf[1] & exp_ovf[0] & (exp_in_00 | exp_in[7]) )
449
                                                           )
450
                ) | (div_inf & op_div & (
451
                                 rmode_00 |
452
                                (rmode[1] & !exp_in_ff & !exp_ovf[1] & !exp_ovf[0] & !r_sign ) |
453
                                (rmode[1] & !exp_ovf[1] & exp_ovf[0] & exp_in_00 & !r_sign)
454
                                )
455
                ) | (op_div & rmode[1] & exp_in_ff & op_dn & !r_sign & (fi_ldz_2 < 24)  & (exp_out_rnd!=8'hfe) );
456
 
457 5 rudi
assign fract_out_final =        (inf_out | ovf0 | output_zero ) ? 23'h0 :
458
                                (max_num | (f2i_max & op_f2i) ) ? 23'h7fffff :
459 2 rudi
                                fract_out_rnd;
460
 
461 5 rudi
assign exp_out_final =  ((op_div & exp_ovf[1] & !exp_ovf[0]) | output_zero ) ? 8'h00 :
462
                        ((op_div & exp_ovf[1] &  exp_ovf[0] & rmode_00) | inf_out | (f2i_max & op_f2i) ) ? 8'hff :
463 2 rudi
                        max_num ? 8'hfe :
464
                        exp_out_rnd;
465
 
466
 
467
// ---------------------------------------------------------------------
468
// Pack Result
469
 
470
assign out = {exp_out_final, fract_out_final};
471
 
472
// ---------------------------------------------------------------------
473
// Exceptions
474
wire            underflow_fmul;
475
wire            overflow_fdiv;
476
wire            undeflow_div;
477
 
478
wire            z =     shft_co | ( exp_ovf[1] |  exp_in_00) |
479
                        (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00));
480
 
481
assign underflow_fmul = ( (|fract_trunc) & z & !exp_in_ff ) |
482
                        (fract_out_00 & !fract_in_00 & exp_ovf[1]);
483
 
484
assign undeflow_div =   !(exp_ovf[1] &  exp_ovf[0] & rmode_00) & !inf_out & !max_num & exp_out_final!=8'hff & (
485
 
486
                        ((|fract_trunc) & !opb_dn & (
487
                                                        ( op_dn & !exp_ovf[1] & exp_ovf[0])      |
488
                                                        ( op_dn &  exp_ovf[1])                  |
489
                                                        ( op_dn &  div_shft1_co)                |
490
                                                          exp_out_00                            |
491
                                                          exp_ovf[1]
492
                                                  )
493
 
494
                        ) |
495
 
496
                        ( exp_ovf[1] & !exp_ovf[0] & (
497
                                                        (  op_dn & exp_in>8'h16 & fi_ldz<23) |
498
                                                        (  op_dn & exp_in<23 & fi_ldz<23 & !rem_00) |
499
                                                        ( !op_dn & (exp_in[7]==exp_div[7]) & !rem_00) |
500
                                                        ( !op_dn & exp_in_00 & (exp_div[7:1]==7'h7f) ) |
501
                                                        ( !op_dn & exp_in<8'h7f & exp_in>8'h20 )
502
                                                        )
503
                        ) |
504
 
505
                        (!exp_ovf[1] & !exp_ovf[0] & (
506
                                                        ( op_dn & fi_ldz<23 & exp_out_00) |
507
                                                        ( exp_in_00 & !rem_00) |
508
                                                        ( !op_dn & ldz_all<23 & exp_in==1 & exp_out_00 & !rem_00)
509
                                                        )
510
                        )
511
 
512
                        );
513
 
514
assign underflow = op_div ? undeflow_div : op_mul ? underflow_fmul : (!fract_in[47] & exp_out1_co) & !dn;
515
 
516
assign overflow_fdiv =  inf_out |
517
                        (!rmode_00 & max_num) |
518
                        (exp_in[7] & op_dn & exp_out_ff) |
519
                        (exp_ovf[0] & (exp_ovf[1] | exp_out_ff) );
520
 
521
assign overflow  = op_div ? overflow_fdiv : (ovf0 | ovf1);
522
 
523 5 rudi
wire            f2i_ine;
524
 
525
assign f2i_ine =        (f2i_zero & !fract_in_00 & !opas) |
526
                        (|fract_trunc) |
527
                        (f2i_zero & (exp_in<8'h80) & opas & !fract_in_00) |
528
                        (f2i_max & rmode_11 & (exp_in<8'h80));
529
 
530
 
531
 
532
assign ine =    op_f2i ? f2i_ine :
533
                op_i2f ? (|fract_trunc) :
534
                ((r & !dn) | (s & !dn) | max_num | (op_div & !rem_00));
535
 
536 2 rudi
// ---------------------------------------------------------------------
537
// Debugging Stuff
538
 
539
// synopsys translate_off
540
 
541
wire    [26:0]   fracta_del, fractb_del;
542
wire    [2:0]    grs_del;
543
wire            dn_del;
544
wire    [7:0]    exp_in_del;
545
wire    [7:0]    exp_out_del;
546
wire    [22:0]   fract_out_del;
547
wire    [47:0]   fract_in_del;
548
wire            overflow_del;
549
wire    [1:0]    exp_ovf_del;
550 5 rudi
wire    [22:0]   fract_out_x_del, fract_out_rnd2a_del;
551 2 rudi
wire    [24:0]   trunc_xx_del;
552
wire            exp_rnd_adj2a_del;
553
wire    [22:0]   fract_dn_del;
554
wire    [4:0]    div_opa_ldz_del;
555
wire    [23:0]   fracta_div_del;
556
wire    [23:0]   fractb_div_del;
557
wire            div_inf_del;
558
wire    [7:0]    fi_ldz_2_del;
559
wire            inf_out_del, max_out_del;
560
wire    [5:0]    fi_ldz_del;
561
wire            rx_del;
562
wire            ez_del;
563 5 rudi
wire            lr;
564
wire    [7:0]    shr, shl, exp_div_del;
565 2 rudi
 
566
delay2 #26 ud000(clk, test.u0.fracta, fracta_del);
567
delay2 #26 ud001(clk, test.u0.fractb, fractb_del);
568
delay1  #2 ud002(clk, {g,r,s}, grs_del);
569
delay1  #0 ud004(clk, dn, dn_del);
570
delay1  #7 ud005(clk, exp_in, exp_in_del);
571
delay1  #7 ud007(clk, exp_out_rnd, exp_out_del);
572
delay1 #47 ud009(clk, fract_in, fract_in_del);
573
delay1  #0 ud010(clk, overflow, overflow_del);
574
delay1  #1 ud011(clk, exp_ovf, exp_ovf_del);
575
delay1 #22 ud014(clk, fract_out, fract_out_x_del);
576
delay1 #24 ud015(clk, fract_trunc, trunc_xx_del);
577
delay1  #0 ud017(clk, exp_rnd_adj2a, exp_rnd_adj2a_del);
578
delay1  #4 ud019(clk, div_opa_ldz, div_opa_ldz_del);
579
delay3 #23 ud020(clk, test.u0.fdiv_opa[49:26],  fracta_div_del);
580
delay3 #23 ud021(clk, test.u0.fractb_mul,       fractb_div_del);
581
delay1  #0 ud023(clk, div_inf, div_inf_del);
582
delay1  #7 ud024(clk, fi_ldz_2, fi_ldz_2_del);
583
delay1  #0 ud025(clk, inf_out, inf_out_del);
584
delay1  #0 ud026(clk, max_num, max_num_del);
585
delay1  #5 ud027(clk, fi_ldz, fi_ldz_del);
586
delay1  #0 ud028(clk, rem_00, rx_del);
587
 
588 5 rudi
delay1  #0 ud029(clk, left_right, lr);
589
delay1  #7 ud030(clk, shift_right, shr);
590
delay1  #7 ud031(clk, shift_left, shl);
591
delay1 #22 ud032(clk, fract_out_rnd2a, fract_out_rnd2a_del);
592
 
593
delay1  #7 ud033(clk, exp_div, exp_div_del);
594
 
595 2 rudi
always @(test.error_event)
596
   begin
597
 
598
        $display("\n----------------------------------------------");
599
 
600
        $display("ERROR: GRS: %b exp_ovf: %b dn: %h exp_in: %h exp_out: %h, exp_rnd_adj2a: %b",
601
                        grs_del, exp_ovf_del, dn_del, exp_in_del, exp_out_del, exp_rnd_adj2a_del);
602
 
603 5 rudi
        $display("      div_opa: %b, div_opb: %b, rem_00: %b, exp_div: %h",
604
                        fracta_div_del, fractb_div_del, rx_del, exp_div_del);
605 2 rudi
 
606 5 rudi
        $display("      lr: %b, shl: %h, shr: %h",
607
                        lr, shl, shr);
608
 
609
 
610 2 rudi
        $display("       overflow: %b, fract_in=%b  fa:%h fb:%h",
611
                        overflow_del, fract_in_del, fracta_del, fractb_del);
612
 
613
        $display("       div_opa_ldz: %h, div_inf: %b, inf_out: %b, max_num: %b, fi_ldz: %h, fi_ldz_2: %h",
614
                        div_opa_ldz_del, div_inf_del, inf_out_del, max_num_del, fi_ldz_del, fi_ldz_2_del);
615
 
616 5 rudi
        $display("       fract_out_x: %b, fract_out_rnd2a_del: %h, fract_trunc: %b\n",
617
                        fract_out_x_del, fract_out_rnd2a_del, trunc_xx_del);
618 2 rudi
   end
619
 
620
 
621
// synopsys translate_on
622
 
623
endmodule
624
 
625
// synopsys translate_off
626
 
627
module delay1(clk, in, out);
628
parameter       N = 1;
629
input   [N:0]    in;
630
output  [N:0]    out;
631
input           clk;
632
 
633
reg     [N:0]    out;
634
 
635
always @(posedge clk)
636
        out <= #1 in;
637
 
638
endmodule
639
 
640
 
641
module delay2(clk, in, out);
642
parameter       N = 1;
643
input   [N:0]    in;
644
output  [N:0]    out;
645
input           clk;
646
 
647
reg     [N:0]    out, r1;
648
 
649
always @(posedge clk)
650
        r1 <= #1 in;
651
 
652
always @(posedge clk)
653
        out <= #1 r1;
654
 
655
endmodule
656
 
657
module delay3(clk, in, out);
658
parameter       N = 1;
659
input   [N:0]    in;
660
output  [N:0]    out;
661
input           clk;
662
 
663
reg     [N:0]    out, r1, r2;
664
 
665
always @(posedge clk)
666
        r1 <= #1 in;
667
 
668
always @(posedge clk)
669
        r2 <= #1 r1;
670
 
671
always @(posedge clk)
672
        out <= #1 r2;
673
 
674
endmodule
675
 
676
// synopsys translate_on

powered by: WebSVN 2.1.0

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