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

Subversion Repositories thor

[/] [thor/] [trunk/] [rtl/] [verilog/] [fpUnit/] [fpRound.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 robfinch
/* ===============================================================
2
        (C) 2006  Robert Finch
3
        All rights reserved.
4
        rob@birdcomputer.ca
5
 
6
        fpRound.v
7
                - floating point rounding unit
8
                - parameterized width
9
                - IEEE 754 representation
10
 
11
        This source code is free for use and modification for
12
        non-commercial or evaluation purposes, provided this
13
        copyright statement and disclaimer remains present in
14
        the file.
15
 
16
        If the code is modified, please state the origin and
17
        note that the code has been modified.
18
 
19
        NO WARRANTY.
20
        THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF
21
        ANY KIND, WHETHER EXPRESS OR IMPLIED. The user must assume
22
        the entire risk of using the Work.
23
 
24
        IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
25
        ANY INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
26
        WHATSOEVER RELATING TO THE USE OF THIS WORK, OR YOUR
27
        RELATIONSHIP WITH THE AUTHOR.
28
 
29
        IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU
30
        TO USE THE WORK IN APPLICATIONS OR SYSTEMS WHERE THE
31
        WORK'S FAILURE TO PERFORM CAN REASONABLY BE EXPECTED
32
        TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN LOSS
33
        OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK,
34
        AND YOU AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS
35
        FROM ANY CLAIMS OR LOSSES RELATING TO SUCH UNAUTHORIZED
36
        USE.
37
 
38
 
39
        This unit takes a normalized floating point number in an
40
        expanded format and rounds it according to the IEEE-754
41
        standard. NaN's and infinities are not rounded.
42
        This module has a single cycle latency.
43
 
44
        Mode
45
        0:              round to nearest even
46
        1:              round to zero (truncate)
47
        2:              round towards +infinity
48
        3:              round towards -infinity
49
 
50
        Ref: Webpack 8.1i  Spartan3-4 xc3s1000-4ft256
51
        69 slices / 129 LUTS / 21.3 ns  (32 bit)
52
=============================================================== */
53
 
54
module fpRound(rm, i, o);
55
parameter WID = 32;
56
localparam MSB = WID-1;
57
localparam EMSB = WID==80 ? 14 :
58
                  WID==64 ? 10 :
59
                                  WID==52 ? 10 :
60
                                  WID==48 ? 10 :
61
                                  WID==44 ? 10 :
62
                                  WID==42 ? 10 :
63
                                  WID==40 ?  9 :
64
                                  WID==32 ?  7 :
65
                                  WID==24 ?  6 : 4;
66
localparam FMSB = WID==80 ? 63 :
67
                  WID==64 ? 51 :
68
                                  WID==52 ? 39 :
69
                                  WID==48 ? 35 :
70
                                  WID==44 ? 31 :
71
                                  WID==42 ? 29 :
72
                                  WID==40 ? 28 :
73
                                  WID==32 ? 22 :
74
                                  WID==24 ? 15 : 9;
75
 
76
input [1:0] rm;                  // rounding mode
77
input [MSB+2:0] i;               // intermediate format input
78
output [WID-1:0] o;              // rounded output
79
 
80
//------------------------------------------------------------
81
// variables
82
wire so;
83
wire [EMSB:0] xo;
84
reg  [FMSB:0] mo;
85
wire [EMSB:0] xo1 = i[MSB+1:FMSB+4];
86
wire [FMSB+3:0] mo1 = i[FMSB+3:0];
87
wire xInf = &xo1;
88
wire dn = !(|xo1);                      // denormalized input
89
assign o = {so,xo,mo};
90
 
91
wire g = i[2];  // guard bit: always the same bit for all operations
92
wire r = i[1];  // rounding bit
93
wire s = i[0];   // sticky bit
94
reg rnd;
95
 
96
// Compute the round bit
97
// Infinities and NaNs are not rounded!
98
always @(xInf,rm,g,r,s,so)
99
        case ({xInf,rm})
100
        3'd0:   rnd = (g & r) | (r & s);        // round to nearest even
101
        3'd1:   rnd = 0;                                 // round to zero (truncate)
102
        3'd2:   rnd = (r | s) & !so;            // round towards +infinity
103
        3'd3:   rnd = (r | s) & so;                     // round towards -infinity
104
        default:        rnd = 0;                         // no rounding if exponent indicates infinite or NaN
105
        endcase
106
 
107
// round the number, check for carry
108
// note: inf. exponent checked above (if the exponent was infinite already, then no rounding occurs as rnd = 0)
109
// note: exponent increments if there is a carry (can only increment to infinity)
110
// performance note: use the carry chain to increment the exponent
111
wire [MSB:0] rounded = {xo1,mo1[FMSB+3:2]} + rnd;
112
wire carry = mo1[FMSB+3] & !rounded[FMSB+1];
113
 
114
assign so = i[MSB+2];
115
assign xo = rounded[MSB:FMSB+2];
116
 
117
always @(rnd or xo or carry or dn or rounded or mo1)
118
        casex({rnd,&xo,carry,dn})
119
        4'b0xx0:        mo = mo1[FMSB+2:1];             // not rounding, not denormalized, => hide MSB
120
        4'b0xx1:        mo = mo1[FMSB+3:2];             // not rounding, denormalized
121
        4'b1000:        mo = rounded[FMSB  :0];  // exponent didn't change, number was normalized, => hide MSB
122
        4'b1001:        mo = rounded[FMSB+1:1]; // exponent didn't change, but number was denormalized, => retain MSB
123
        4'b1010:        mo = rounded[FMSB+1:1]; // exponent incremented (new MSB generated), number was normalized, => hide 'extra (FMSB+2)' MSB
124
        4'b1011:        mo = rounded[FMSB+1:1]; // exponent incremented (new MSB generated), number was denormalized, number became normalized, => hide 'extra (FMSB+2)' MSB
125
        4'b11xx:        mo = 0;                                  // number became infinite, no need to check carry etc., rnd would be zero if input was NaN or infinite
126
        endcase
127
 
128
endmodule
129
 
130
 
131
// Round and register the output
132
 
133
module fpRoundReg(clk, ce, rm, i, o);
134
parameter WID = 32;
135
localparam MSB = WID-1;
136
localparam EMSB = WID==80 ? 14 :
137
                  WID==64 ? 10 :
138
                                  WID==52 ? 10 :
139
                                  WID==48 ? 10 :
140
                                  WID==44 ? 10 :
141
                                  WID==42 ? 10 :
142
                                  WID==40 ?  9 :
143
                                  WID==32 ?  7 :
144
                                  WID==24 ?  6 : 4;
145
localparam FMSB = WID==80 ? 63 :
146
                  WID==64 ? 51 :
147
                                  WID==52 ? 39 :
148
                                  WID==48 ? 35 :
149
                                  WID==44 ? 31 :
150
                                  WID==42 ? 29 :
151
                                  WID==40 ? 28 :
152
                                  WID==32 ? 22 :
153
                                  WID==24 ? 15 : 9;
154
 
155
input clk;
156
input ce;
157
input [1:0] rm;                  // rounding mode
158
input [MSB+2:0] i;               // expanded format input
159
output reg [WID-1:0] o;          // rounded output
160
 
161
wire [WID-1:0] o1;
162
fpRound #(WID) u1 (.rm(rm), .i(i), .o(o1) );
163
 
164
always @(posedge clk)
165
        if (ce)
166
                o <= o1;
167
 
168
endmodule

powered by: WebSVN 2.1.0

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