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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [DFPRound128.sv] - Blame information for rev 70

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 57 robfinch
// ============================================================================
2
//        __
3 70 robfinch
//   \\__/ o\    (C) 2006-2022  Robert Finch, Waterloo
4 57 robfinch
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//      DFPRound128.sv
9
//    - decimal floating point rounding unit
10
//    - parameterized width
11
//
12
//
13
// BSD 3-Clause License
14
// Redistribution and use in source and binary forms, with or without
15
// modification, are permitted provided that the following conditions are met:
16
//
17
// 1. Redistributions of source code must retain the above copyright notice, this
18
//    list of conditions and the following disclaimer.
19
//
20
// 2. Redistributions in binary form must reproduce the above copyright notice,
21
//    this list of conditions and the following disclaimer in the documentation
22
//    and/or other materials provided with the distribution.
23
//
24
// 3. Neither the name of the copyright holder nor the names of its
25
//    contributors may be used to endorse or promote products derived from
26
//    this software without specific prior written permission.
27
//
28
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
//
39
// ============================================================================
40
 
41
import DFPPkg::*;
42
 
43
`ifdef MIN_LATENCY
44
`define PIPE_ADV  *
45
`else
46
`define PIPE_ADV  (posedge clk)
47
`endif
48
 
49
module DFPRound128(clk, ce, rm, i, o);
50
parameter N=34;
51
input clk;
52
input ce;
53
input [2:0] rm;                 // rounding mode
54
input DFP128UN i;               // intermediate format input
55 64 robfinch
output DFP128 o;                // packed rounded output
56 57 robfinch
 
57
parameter ROUND_CEILING = 3'd0;
58
parameter ROUND_FLOOR = 3'd1;
59
parameter ROUND_HALF_UP = 3'd2;
60
parameter ROUND_HALF_EVEN = 3'd3;
61
parameter ROUND_DOWN = 3'd4;
62
 
63
//------------------------------------------------------------
64
// variables
65
wire nano, qnano, snano;
66
wire infinity;
67
wire so;
68
wire [13:0] xo;
69
reg  [N*4-1:0] mo;
70
reg [13:0] xo1;
71
reg [N*4-1:0] mo1;
72
wire xInf = i.exp==14'h3FFF;
73
wire so0 = i.sign;
74
 
75
wire [3:0] l = i.sig[7:4];
76
wire [3:0] r = i.sig[3:0];
77
 
78
reg rnd;
79
 
80
//------------------------------------------------------------
81
// Clock #1
82
// - determine round amount (add 1 or 0)
83
//------------------------------------------------------------
84
 
85
always @`PIPE_ADV
86
if (ce) xo1 <= i.exp;
87
always @`PIPE_ADV
88
if (ce) mo1 <= i.sig[(N+1)*4-1:4];
89
 
90
// Compute the round bit
91
// Infinities and NaNs are not rounded!
92
always @`PIPE_ADV
93
if (ce)
94
        if (i.nan | i.infinity)
95
                rnd = 1'b0;
96
        else
97
                case (rm)
98
                ROUND_CEILING:  rnd <= (r == 4'd0 || i.sign==1'b1) ? 1'b0 : 1'b1;
99
                ROUND_FLOOR:            rnd <= (r == 4'd0 || i.sign==1'b0) ? 1'b0 : 1'b1;
100
                ROUND_HALF_UP:  rnd <= r >= 4'h5;
101
                ROUND_HALF_EVEN:        rnd <= r==4'h5 ? l[0] : r > 4'h5 ? 1'b1 : 1'b0;
102
                ROUND_DOWN:                     rnd <= 1'b0;
103
                default:                                rnd <= 1'b0;
104
                endcase
105
 
106
//------------------------------------------------------------
107
// Clock #2
108
// round the number, check for carry
109
// note: inf. exponent checked above (if the exponent was infinite already, then no rounding occurs as rnd = 0)
110
// note: exponent increments if there is a carry (can only increment to infinity)
111
//------------------------------------------------------------
112
 
113
wire [N*4-1:0] rounded1;
114
wire cobcd;
115
 
116
BCDAddN #(.N(N)) ubcdan1
117
(
118
        .ci(1'b0),
119
        .a(mo1),
120
        .b({{N*4-1{1'd0}},rnd}),
121
        .o(rounded1),
122
        .co(cobcd)
123
);
124
 
125
reg [N*4-1:0] rounded2;
126
reg rnd2;
127
reg dn2;
128
reg [14:0] xo2;
129
always @`PIPE_ADV
130
        if (ce) rounded2 <= rounded1;
131
always @`PIPE_ADV
132
        if (ce) rnd2 <= rnd;
133
always @`PIPE_ADV
134
        if (ce) dn2 <= !(|xo1);
135
always @`PIPE_ADV
136
        if (ce) xo2 <= xo1 + cobcd;
137
 
138
//------------------------------------------------------------
139
// Clock #3
140
// - shift mantissa if required.
141
//------------------------------------------------------------
142
wire infinity2;
143
`ifdef MIN_LATENCY
144
assign nano = i.nan;
145
assign qnano = i.qnan;
146
assign snano = i.snan;
147
assign infinity = i.infinity | (rnd2 && xo2[13:0]==14'h3FFF);
148
assign so = i.sign;
149
assign xo = xo2[13:0];
150
`else
151
delay3 #(1) u21 (.clk(clk), .ce(ce), .i(i.nan), .o(nano));
152
delay3 #(1) u22 (.clk(clk), .ce(ce), .i(i.qnan), .o(qnano));
153
delay3 #(1) u23 (.clk(clk), .ce(ce), .i(i.snan), .o(snano));
154
delay2 #(1) u24 (.clk(clk), .ce(ce), .i(i.infinity), .o(infinity2));
155
delay3 #(1) u25 (.clk(clk), .ce(ce), .i(i.sign), .o(so));
156
delay1 #(14) u26 (.clk(clk), .ce(ce), .i(xo2[13:0]), .o(xo));
157
delay1 #(1) u27 (.clk(clk), .ce(ce), .i(infinity2 | (rnd2 && xo2[13:0]==14'h3FFF)), .o(infinity));
158
`endif
159
 
160
wire carry2 = xo2[14];
161
 
162
always @`PIPE_ADV
163
if (ce)
164
        casez({rnd2,xo2[13:0]==14'h3FFF,carry2,dn2})
165
        4'b0??0:        mo <= mo1[N*4-1:0];                                                     // not rounding, not denormalized
166
        4'b0??1:        mo <= mo1[N*4-1:0];                                                     // not rounding, denormalized
167
        4'b1000:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, number was normalized
168
        4'b1001:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, but number was denormalized
169
        4'b1010:        mo <= {4'h1,rounded2[N*4-1: 4]};        // exponent incremented (new MSD generated), number was normalized
170
        4'b1011:        mo <= rounded2[N*4-1:0];                                        // exponent incremented (new MSB generated), number was denormalized, number became normalized
171
        4'b11??:        mo <= {N*4{1'd0}};                                                                      // number became infinite, no need to check carry etc., rnd would be zero if input was NaN or infinite
172
        endcase
173
 
174 64 robfinch
//------------------------------------------------------------
175
// Clock #4
176
// - Pack output
177
//------------------------------------------------------------
178
 
179
DFP128U o1;
180
DFP128 o2;
181
 
182
assign o1.nan = nano;
183
assign o1.qnan = qnano;
184
assign o1.snan = snano;
185
assign o1.infinity = infinity;
186
assign o1.sign = so;
187
assign o1.exp = xo;
188
assign o1.sig = mo;
189
 
190
DFPPack128 u41 (o1, o2);
191
always_ff @(posedge clk)
192
        if (ce) o <= o2;
193
 
194 57 robfinch
endmodule

powered by: WebSVN 2.1.0

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