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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [DFPRound.sv] - Blame information for rev 50

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

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

powered by: WebSVN 2.1.0

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