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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_fpu_post_norm_mul.v] - Blame information for rev 588

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

Line No. Rev Author Line
1 258 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  or1200_fpu_post_norm_mul                                    ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6
////  http://opencores.org/project,or1k                           ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  post-normalization entity for the multiplication unit       ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////                                                              ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Original design (FPU100) -                            ////
16
////        Jidan Al-eryani, jidan@gmx.net                        ////
17
////      - Conv. to Verilog and inclusion in OR1200 -            ////
18
////        Julius Baxter, julius@opencores.org                   ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21
//
22
//  Copyright (C) 2006, 2010
23
//
24
//      This source file may be used and distributed without        
25
//      restriction provided that this copyright statement is not   
26
//      removed from the file and that any derivative work contains 
27
//      the original copyright notice and the associated disclaimer.
28
//                                                           
29
//              THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     
30
//      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   
31
//      TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   
32
//      FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      
33
//      OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         
34
//      INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    
35
//      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   
36
//      GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        
37
//      BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  
38
//      LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  
39
//      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  
40
//      OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         
41
//      POSSIBILITY OF SUCH DAMAGE. 
42
//
43
 
44
module or1200_fpu_post_norm_mul(
45
                     clk_i,
46
                     opa_i,
47
                     opb_i,
48
                     exp_10_i,
49
                     fract_48_i,
50
                     sign_i,
51
                     rmode_i,
52
                     output_o,
53
                     ine_o
54
                     );
55
 
56
   parameter FP_WIDTH = 32;
57
   parameter MUL_SERIAL = 0; // 0 for parallel multiplier, 1 for serial
58
   parameter MUL_COUNT = 11; //11 for parallel multiplier, 34 for serial
59
   parameter FRAC_WIDTH = 23;
60
   parameter EXP_WIDTH = 8;
61
   parameter ZERO_VECTOR = 31'd0;
62
   parameter INF = 31'b1111111100000000000000000000000;
63
   parameter QNAN = 31'b1111111110000000000000000000000;
64
   parameter SNAN = 31'b1111111100000000000000000000001;
65
 
66
   input clk_i;
67
   input [FP_WIDTH-1:0] opa_i;
68
   input [FP_WIDTH-1:0] opb_i;
69
   input [EXP_WIDTH+1:0] exp_10_i;
70
   input [2*FRAC_WIDTH+1:0] fract_48_i;
71
   input                    sign_i;
72
   input [1:0]               rmode_i;
73
   output reg [FP_WIDTH-1:0]    output_o;
74
   output reg               ine_o;
75
 
76
 
77
   reg [EXP_WIDTH-1:0]     s_expa;
78
   reg [EXP_WIDTH-1:0]     s_expb;
79
   reg [EXP_WIDTH+1:0]     s_exp_10_i;
80
   reg [2*FRAC_WIDTH+1:0]  s_fract_48_i;
81
   reg                     s_sign_i;
82
   wire [FP_WIDTH-1:0]       s_output_o;
83
   wire                     s_ine_o;
84
   wire                     s_overflow;
85
   reg [FP_WIDTH-1:0]        s_opa_i;
86
   reg [FP_WIDTH-1:0]        s_opb_i;
87
   reg [1:0]                 s_rmode_i;
88
 
89
   reg [5:0]                 s_zeros;
90
   wire                     s_carry;
91
   reg [5:0]                 s_shr2;
92
   reg [5:0]                 s_shl2;
93
   reg [8:0]                 s_expo1;
94
   wire [8:0]                s_expo2b;
95
   wire [9:0]                s_exp_10a;
96
   wire [9:0]                s_exp_10b;
97
   reg [47:0]                s_frac2a;
98
 
99
   wire                     s_sticky, s_guard, s_round;
100
   wire                     s_roundup;
101
   reg [24:0]                s_frac_rnd;
102
   wire [24:0]               s_frac3;
103
   wire                     s_shr3;
104
   reg [5:0]                 s_r_zeros;
105
   wire                     s_lost;
106
   wire                     s_op_0;
107
   wire [8:0]                s_expo3;
108
 
109
   wire                     s_infa, s_infb;
110
   wire                     s_nan_in, s_nan_op, s_nan_a, s_nan_b;
111
 
112
 
113
   // Input Register
114
   always @(posedge clk_i)
115
     begin
116
        s_opa_i <= opa_i;
117
        s_opb_i <= opb_i;
118
        s_expa <= opa_i[30:23];
119
        s_expb <= opb_i[30:23];
120
        s_exp_10_i <= exp_10_i;
121
        s_fract_48_i <= fract_48_i;
122
        s_sign_i <= sign_i;
123
        s_rmode_i <= rmode_i;
124
     end
125
 
126
   // Output register
127
   always @(posedge clk_i)
128
     begin
129
        output_o <= s_output_o;
130
        ine_o   <= s_ine_o;
131
     end
132
 
133
   //*** Stage 1 ****
134
   // figure out the exponent and howmuch the fraction has to be shiftd 
135
   // right/left
136
 
137
   assign s_carry = s_fract_48_i[47];
138
 
139
 
140
   always @(posedge clk_i)
141
     if (!s_fract_48_i[47])
142 364 julius
       casez(s_fract_48_i[46:1])        // synopsys full_case parallel_case
143 258 julius
         46'b1?????????????????????????????????????????????: s_zeros <=  0;
144
         46'b01????????????????????????????????????????????: s_zeros <=  1;
145
         46'b001???????????????????????????????????????????: s_zeros <=  2;
146
         46'b0001??????????????????????????????????????????: s_zeros <=  3;
147
         46'b00001?????????????????????????????????????????: s_zeros <=  4;
148
         46'b000001????????????????????????????????????????: s_zeros <=  5;
149
         46'b0000001???????????????????????????????????????: s_zeros <=  6;
150
         46'b00000001??????????????????????????????????????: s_zeros <=  7;
151
         46'b000000001?????????????????????????????????????: s_zeros <=  8;
152
         46'b0000000001????????????????????????????????????: s_zeros <=  9;
153
         46'b00000000001???????????????????????????????????: s_zeros <=  10;
154
         46'b000000000001??????????????????????????????????: s_zeros <=  11;
155
         46'b0000000000001?????????????????????????????????: s_zeros <=  12;
156
         46'b00000000000001????????????????????????????????: s_zeros <=  13;
157
         46'b000000000000001???????????????????????????????: s_zeros <=  14;
158
         46'b0000000000000001??????????????????????????????: s_zeros <=  15;
159
         46'b00000000000000001?????????????????????????????: s_zeros <=  16;
160
         46'b000000000000000001????????????????????????????: s_zeros <=  17;
161
         46'b0000000000000000001???????????????????????????: s_zeros <=  18;
162
         46'b00000000000000000001??????????????????????????: s_zeros <=  19;
163
         46'b000000000000000000001?????????????????????????: s_zeros <=  20;
164
         46'b0000000000000000000001????????????????????????: s_zeros <=  21;
165
         46'b00000000000000000000001???????????????????????: s_zeros <=  22;
166
         46'b000000000000000000000001??????????????????????: s_zeros <=  23;
167
         46'b0000000000000000000000001?????????????????????: s_zeros <=  24;
168
         46'b00000000000000000000000001????????????????????: s_zeros <=  25;
169
         46'b000000000000000000000000001???????????????????: s_zeros <=  26;
170
         46'b0000000000000000000000000001??????????????????: s_zeros <=  27;
171
         46'b00000000000000000000000000001?????????????????: s_zeros <=  28;
172
         46'b000000000000000000000000000001????????????????: s_zeros <=  29;
173
         46'b0000000000000000000000000000001???????????????: s_zeros <=  30;
174
         46'b00000000000000000000000000000001??????????????: s_zeros <=  31;
175
         46'b000000000000000000000000000000001?????????????: s_zeros <=  32;
176
         46'b0000000000000000000000000000000001????????????: s_zeros <=  33;
177
         46'b00000000000000000000000000000000001???????????: s_zeros <=  34;
178
         46'b000000000000000000000000000000000001??????????: s_zeros <=  35;
179
         46'b0000000000000000000000000000000000001?????????: s_zeros <=  36;
180
         46'b00000000000000000000000000000000000001????????: s_zeros <=  37;
181
         46'b000000000000000000000000000000000000001???????: s_zeros <=  38;
182
         46'b0000000000000000000000000000000000000001??????: s_zeros <=  39;
183
         46'b00000000000000000000000000000000000000001?????: s_zeros <=  40;
184
         46'b000000000000000000000000000000000000000001????: s_zeros <=  41;
185
         46'b0000000000000000000000000000000000000000001???: s_zeros <=  42;
186
         46'b00000000000000000000000000000000000000000001??: s_zeros <=  43;
187
         46'b000000000000000000000000000000000000000000001?: s_zeros <=  44;
188
         46'b0000000000000000000000000000000000000000000001: s_zeros <=  45;
189
         46'b0000000000000000000000000000000000000000000000: s_zeros <=  46;
190
       endcase // casex (s_fract_48_i[46:1])
191
     else
192
       s_zeros <= 0;
193
 
194
 
195
   always @(posedge clk_i)
196 364 julius
     casez(s_fract_48_i) // synopsys full_case parallel_case
197 258 julius
       48'b???????????????????????????????????????????????1: s_r_zeros <=  0;
198
       48'b??????????????????????????????????????????????10: s_r_zeros <=  1;
199
       48'b?????????????????????????????????????????????100: s_r_zeros <=  2;
200
       48'b????????????????????????????????????????????1000: s_r_zeros <=  3;
201
       48'b???????????????????????????????????????????10000: s_r_zeros <=  4;
202
       48'b??????????????????????????????????????????100000: s_r_zeros <=  5;
203
       48'b?????????????????????????????????????????1000000: s_r_zeros <=  6;
204
       48'b????????????????????????????????????????10000000: s_r_zeros <=  7;
205
       48'b???????????????????????????????????????100000000: s_r_zeros <=  8;
206
       48'b??????????????????????????????????????1000000000: s_r_zeros <=  9;
207
       48'b?????????????????????????????????????10000000000: s_r_zeros <=  10;
208
       48'b????????????????????????????????????100000000000: s_r_zeros <=  11;
209
       48'b???????????????????????????????????1000000000000: s_r_zeros <=  12;
210
       48'b??????????????????????????????????10000000000000: s_r_zeros <=  13;
211
       48'b?????????????????????????????????100000000000000: s_r_zeros <=  14;
212
       48'b????????????????????????????????1000000000000000: s_r_zeros <=  15;
213
       48'b???????????????????????????????10000000000000000: s_r_zeros <=  16;
214
       48'b??????????????????????????????100000000000000000: s_r_zeros <=  17;
215
       48'b?????????????????????????????1000000000000000000: s_r_zeros <=  18;
216
       48'b????????????????????????????10000000000000000000: s_r_zeros <=  19;
217
       48'b???????????????????????????100000000000000000000: s_r_zeros <=  20;
218
       48'b??????????????????????????1000000000000000000000: s_r_zeros <=  21;
219
       48'b?????????????????????????10000000000000000000000: s_r_zeros <=  22;
220
       48'b????????????????????????100000000000000000000000: s_r_zeros <=  23;
221
       48'b???????????????????????1000000000000000000000000: s_r_zeros <=  24;
222
       48'b??????????????????????10000000000000000000000000: s_r_zeros <=  25;
223
       48'b?????????????????????100000000000000000000000000: s_r_zeros <=  26;
224
       48'b????????????????????1000000000000000000000000000: s_r_zeros <=  27;
225
       48'b???????????????????10000000000000000000000000000: s_r_zeros <=  28;
226
       48'b??????????????????100000000000000000000000000000: s_r_zeros <=  29;
227
       48'b?????????????????1000000000000000000000000000000: s_r_zeros <=  30;
228
       48'b????????????????10000000000000000000000000000000: s_r_zeros <=  31;
229
       48'b???????????????100000000000000000000000000000000: s_r_zeros <=  32;
230
       48'b??????????????1000000000000000000000000000000000: s_r_zeros <=  33;
231
       48'b?????????????10000000000000000000000000000000000: s_r_zeros <=  34;
232
       48'b????????????100000000000000000000000000000000000: s_r_zeros <=  35;
233
       48'b???????????1000000000000000000000000000000000000: s_r_zeros <=  36;
234
       48'b??????????10000000000000000000000000000000000000: s_r_zeros <=  37;
235
       48'b?????????100000000000000000000000000000000000000: s_r_zeros <=  38;
236
       48'b????????1000000000000000000000000000000000000000: s_r_zeros <=  39;
237
       48'b???????10000000000000000000000000000000000000000: s_r_zeros <=  40;
238
       48'b??????100000000000000000000000000000000000000000: s_r_zeros <=  41;
239
       48'b?????1000000000000000000000000000000000000000000: s_r_zeros <=  42;
240
       48'b????10000000000000000000000000000000000000000000: s_r_zeros <=  43;
241
       48'b???100000000000000000000000000000000000000000000: s_r_zeros <=  44;
242
       48'b??1000000000000000000000000000000000000000000000: s_r_zeros <=  45;
243
       48'b?10000000000000000000000000000000000000000000000: s_r_zeros <=  46;
244
       48'b100000000000000000000000000000000000000000000000: s_r_zeros <=  47;
245
       48'b000000000000000000000000000000000000000000000000: s_r_zeros <=  48;
246
     endcase // casex (s_fract_48_i)
247
 
248
   assign s_exp_10a = s_exp_10_i + {9'd0,s_carry};
249
   assign s_exp_10b = s_exp_10a - {4'd0,s_zeros};
250
 
251
   wire [9:0] v_shr1;
252
   wire [9:0] v_shl1;
253
 
254
   assign v_shr1 = (s_exp_10a[9] | !(|s_exp_10a)) ?
255
                   10'd1 - s_exp_10a + {9'd0,s_carry} :
256
                   (s_exp_10b[9] | !(|s_exp_10b)) ?
257
 
258
                   s_exp_10b[8] ?
259
 
260
 
261
   assign v_shl1 = (s_exp_10a[9] | !(|s_exp_10a)) ?
262
 
263
                   (s_exp_10b[9] | !(|s_exp_10b)) ?
264
                   {4'd0,s_zeros} - s_exp_10a :
265
                   s_exp_10b[8] ?
266
 
267
 
268
 
269
   always @(posedge clk_i)
270
     begin
271
        if ((s_exp_10a[9] | !(|s_exp_10a)))
272
          s_expo1 <= 9'd1;
273
        else if (s_exp_10b[9] | !(|s_exp_10b))
274 364 julius
          s_expo1 <= 9'd1;
275 258 julius
        else if (s_exp_10b[8])
276
          s_expo1 <= 9'b011111111;
277
        else
278
          s_expo1 <= s_exp_10b[8:0];
279
 
280
        if (v_shr1[6])
281
          s_shr2 <= {6{1'b1}};
282
        else
283
          s_shr2 <= v_shr1[5:0];
284
 
285
        s_shl2 <= v_shl1[5:0];
286
     end // always @ (posedge clk_i)
287
 
288
   // *** Stage 2 ***
289
   // Shifting the fraction and rounding
290
 
291
 
292
   // shift the fraction
293
   always @(posedge clk_i)
294
     if (|s_shr2)
295
       s_frac2a <= s_fract_48_i >> s_shr2;
296
     else
297
       s_frac2a <= s_fract_48_i << s_shl2;
298
 
299
   assign s_expo2b = s_frac2a[46] ? s_expo1 : s_expo1 - 9'd1;
300
 
301
   // signals if precision was last during the right-shift above
302
   assign s_lost = (s_shr2 + {5'd0,s_shr3}) > s_r_zeros;
303
 
304
   // ***Stage 3***
305
   // Rounding
306
 
307
   //                                                              23
308
   //                                                                   |       
309
   //                   xx00000000000000000000000grsxxxxxxxxxxxxxxxxxxxx
310
   // guard bit: s_frac2a[23] (LSB of output)
311
   // round bit: s_frac2a[22]
312
   assign s_guard = s_frac2a[22];
313
   assign s_round = s_frac2a[21];
314
   assign s_sticky = (|s_frac2a[20:0]) | s_lost;
315
 
316
   assign s_roundup = s_rmode_i==2'b00 ? // round to nearest even
317
                      s_guard & ((s_round | s_sticky) | s_frac2a[23]) :
318
                      s_rmode_i==2'b10 ? // round up
319
                      (s_guard | s_round | s_sticky) & !s_sign_i :
320
                      s_rmode_i==2'b11 ? // round down
321
                      (s_guard | s_round | s_sticky) & s_sign_i :
322
                      0; // round to zero(truncate = no rounding)
323
 
324
 
325
   always @(posedge clk_i)
326
     if (s_roundup)
327
       s_frac_rnd <= s_frac2a[47:23] + 1;
328
     else
329
       s_frac_rnd <= s_frac2a[47:23];
330
 
331
   assign s_shr3 = s_frac_rnd[24];
332
 
333
 
334
   assign s_expo3 = (s_shr3 & (s_expo2b!=9'b011111111)) ?
335
                     s_expo2b + 1 : s_expo2b;
336
 
337
   assign s_frac3 = (s_shr3 & (s_expo2b!=9'b011111111)) ?
338
                     {1'b0,s_frac_rnd[24:1]} : s_frac_rnd;
339
 
340
   //-***Stage 4****
341
   // Output
342
 
343
   assign s_op_0 = !((|s_opa_i[30:0]) & (|s_opb_i[30:0]));
344
 
345
   assign s_infa = &s_expa;
346
 
347
   assign s_infb = &s_expb;
348
 
349
   assign s_nan_a = s_infa & (|s_opa_i[22:0]);
350
 
351
   assign s_nan_b = s_infb & (|s_opb_i[22:0]);
352
 
353
   assign s_nan_in = s_nan_a | s_nan_b;
354
 
355
   assign s_nan_op = (s_infa | s_infb) & s_op_0; // 0 * inf = nan
356
 
357
   assign s_overflow = (s_expo3==9'b011111111) & !(s_infa | s_infb);
358
 
359
   assign s_ine_o = !s_op_0 & (s_lost | (|s_frac2a[22:0]) | s_overflow);
360
 
361
   assign s_output_o = (s_nan_in | s_nan_op) ?
362
                       {s_sign_i,QNAN} :
363
                       (s_infa | s_infb) | s_overflow ?
364
                       {s_sign_i,INF} :
365
                       s_r_zeros==48 ?
366
                       {s_sign_i,ZERO_VECTOR} :
367
                       {s_sign_i,s_expo3[7:0],s_frac3[22:0]};
368
 
369
endmodule // or1200_fpu_post_norm_mul
370
 

powered by: WebSVN 2.1.0

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