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

Subversion Repositories ft816float

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

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

Line No. Rev Author Line
1 57 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2006-2020  Robert Finch, Waterloo
4
//    \  __ /    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
output DFP128U o;               // rounded output
56
 
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
assign o = {so,xo,mo};
75
 
76
assign o.nan = nano;
77
assign o.qnan = qnano;
78
assign o.snan = snano;
79
assign o.infinity = infinity;
80
assign o.sign = so;
81
assign o.exp = xo;
82
assign o.sig = mo;
83
 
84
wire [3:0] l = i.sig[7:4];
85
wire [3:0] r = i.sig[3:0];
86
 
87
reg rnd;
88
 
89
//------------------------------------------------------------
90
// Clock #1
91
// - determine round amount (add 1 or 0)
92
//------------------------------------------------------------
93
 
94
always @`PIPE_ADV
95
if (ce) xo1 <= i.exp;
96
always @`PIPE_ADV
97
if (ce) mo1 <= i.sig[(N+1)*4-1:4];
98
 
99
// Compute the round bit
100
// Infinities and NaNs are not rounded!
101
always @`PIPE_ADV
102
if (ce)
103
        if (i.nan | i.infinity)
104
                rnd = 1'b0;
105
        else
106
                case (rm)
107
                ROUND_CEILING:  rnd <= (r == 4'd0 || i.sign==1'b1) ? 1'b0 : 1'b1;
108
                ROUND_FLOOR:            rnd <= (r == 4'd0 || i.sign==1'b0) ? 1'b0 : 1'b1;
109
                ROUND_HALF_UP:  rnd <= r >= 4'h5;
110
                ROUND_HALF_EVEN:        rnd <= r==4'h5 ? l[0] : r > 4'h5 ? 1'b1 : 1'b0;
111
                ROUND_DOWN:                     rnd <= 1'b0;
112
                default:                                rnd <= 1'b0;
113
                endcase
114
 
115
//------------------------------------------------------------
116
// Clock #2
117
// round the number, check for carry
118
// note: inf. exponent checked above (if the exponent was infinite already, then no rounding occurs as rnd = 0)
119
// note: exponent increments if there is a carry (can only increment to infinity)
120
//------------------------------------------------------------
121
 
122
wire [N*4-1:0] rounded1;
123
wire cobcd;
124
 
125
BCDAddN #(.N(N)) ubcdan1
126
(
127
        .ci(1'b0),
128
        .a(mo1),
129
        .b({{N*4-1{1'd0}},rnd}),
130
        .o(rounded1),
131
        .co(cobcd)
132
);
133
 
134
reg [N*4-1:0] rounded2;
135
reg rnd2;
136
reg dn2;
137
reg [14:0] xo2;
138
always @`PIPE_ADV
139
        if (ce) rounded2 <= rounded1;
140
always @`PIPE_ADV
141
        if (ce) rnd2 <= rnd;
142
always @`PIPE_ADV
143
        if (ce) dn2 <= !(|xo1);
144
always @`PIPE_ADV
145
        if (ce) xo2 <= xo1 + cobcd;
146
 
147
//------------------------------------------------------------
148
// Clock #3
149
// - shift mantissa if required.
150
//------------------------------------------------------------
151
wire infinity2;
152
`ifdef MIN_LATENCY
153
assign nano = i.nan;
154
assign qnano = i.qnan;
155
assign snano = i.snan;
156
assign infinity = i.infinity | (rnd2 && xo2[13:0]==14'h3FFF);
157
assign so = i.sign;
158
assign xo = xo2[13:0];
159
`else
160
delay3 #(1) u21 (.clk(clk), .ce(ce), .i(i.nan), .o(nano));
161
delay3 #(1) u22 (.clk(clk), .ce(ce), .i(i.qnan), .o(qnano));
162
delay3 #(1) u23 (.clk(clk), .ce(ce), .i(i.snan), .o(snano));
163
delay2 #(1) u24 (.clk(clk), .ce(ce), .i(i.infinity), .o(infinity2));
164
delay3 #(1) u25 (.clk(clk), .ce(ce), .i(i.sign), .o(so));
165
delay1 #(14) u26 (.clk(clk), .ce(ce), .i(xo2[13:0]), .o(xo));
166
delay1 #(1) u27 (.clk(clk), .ce(ce), .i(infinity2 | (rnd2 && xo2[13:0]==14'h3FFF)), .o(infinity));
167
`endif
168
 
169
wire carry2 = xo2[14];
170
 
171
always @`PIPE_ADV
172
if (ce)
173
        casez({rnd2,xo2[13:0]==14'h3FFF,carry2,dn2})
174
        4'b0??0:        mo <= mo1[N*4-1:0];                                                     // not rounding, not denormalized
175
        4'b0??1:        mo <= mo1[N*4-1:0];                                                     // not rounding, denormalized
176
        4'b1000:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, number was normalized
177
        4'b1001:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, but number was denormalized
178
        4'b1010:        mo <= {4'h1,rounded2[N*4-1: 4]};        // exponent incremented (new MSD generated), number was normalized
179
        4'b1011:        mo <= rounded2[N*4-1:0];                                        // exponent incremented (new MSB generated), number was denormalized, number became normalized
180
        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
181
        endcase
182
 
183
endmodule

powered by: WebSVN 2.1.0

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