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

Subversion Repositories ft816float

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

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 55 robfinch
parameter N=33;
52 50 robfinch
input clk;
53
input ce;
54
input [2:0] rm;                 // rounding mode
55 55 robfinch
input [N*4+16+4+4-1:0] i;               // intermediate format input
56
output [N*4+16+4-1:0] o;                // rounded output
57 50 robfinch
 
58
parameter ROUND_CEILING = 3'd0;
59
parameter ROUND_FLOOR = 3'd1;
60
parameter ROUND_HALF_UP = 3'd2;
61
parameter ROUND_HALF_EVEN = 3'd3;
62
parameter ROUND_DOWN = 3'd4;
63
 
64
//------------------------------------------------------------
65
// variables
66
wire [3:0] so;
67
wire [15:0] xo;
68 55 robfinch
reg  [N*4-1:0] mo;
69 50 robfinch
reg [15:0] xo1;
70 55 robfinch
reg [N*4-1:0] mo1;
71
wire xInf = i[N*4+16+4-1:(N+1)*4]==16'h9999;
72
wire so0 = i[N*4+16+4-2];
73 51 robfinch
assign o = {so,xo,mo};
74 50 robfinch
 
75
wire [3:0] l = i[7:4];
76
wire [3:0] r = i[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 55 robfinch
if (ce) xo1 <= i[N*4+16+4-1:(N+1)*4];
87 50 robfinch
always @`PIPE_ADV
88 55 robfinch
if (ce) mo1 <= i[(N+1)*4-1:4];
89 50 robfinch
 
90
// Compute the round bit
91
// Infinities and NaNs are not rounded!
92
always @`PIPE_ADV
93
if (ce)
94
        if (|so[1:0])
95
                rnd = 1'b0;
96
        else
97
                case (rm)
98
                ROUND_CEILING:  rnd <= (r == 4'd0 || so[2]==1'b0) ? 1'b0 : 1'b1;
99
                ROUND_FLOOR:            rnd <= (r == 4'd0 || so[2]==1'b1) ? 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 55 robfinch
wire [N*4+16+4-1-4:0] rounded1;
114 50 robfinch
wire co1;
115
 
116 55 robfinch
BCDAddN #(.N(N+4)) ubcdan1
117 50 robfinch
(
118
        .ci(1'b0),
119
        .a({xo1,mo1}),
120 55 robfinch
        .b({{N*4+16+4-1-4{1'd0}},rnd}),
121 50 robfinch
        .o(rounded1),
122
        .co(co1)
123
);
124
 
125
 
126 55 robfinch
reg [N*4+16+4-1-4:0] rounded2;
127 50 robfinch
reg carry2;
128
reg rnd2;
129
reg dn2;
130
wire [15:0] xo2;
131
always @`PIPE_ADV
132
        if (ce) rounded2 <= rounded1;
133
always @`PIPE_ADV
134
        if (ce) carry2 <= co1;
135
always @`PIPE_ADV
136
        if (ce) rnd2 <= rnd;
137
always @`PIPE_ADV
138
        if (ce) dn2 <= !(|xo1);
139 55 robfinch
assign xo2 = rounded2[N*4+16+4-1-4:N*4];
140 50 robfinch
 
141
//------------------------------------------------------------
142
// Clock #3
143
// - shift mantissa if required.
144
//------------------------------------------------------------
145
`ifdef MIN_LATENCY
146 55 robfinch
assign so = i[N*4+16+4+3:N*4+16+4];
147 50 robfinch
assign xo = xo2;
148
`else
149 55 robfinch
delay3 #(4) u21 (.clk(clk), .ce(ce), .i(i[N*4+16+4+3:N*4+16+4]), .o(so));
150 50 robfinch
delay1 #(16) u22 (.clk(clk), .ce(ce), .i(xo2), .o(xo));
151
`endif
152
 
153
always @`PIPE_ADV
154
if (ce)
155
        casez({rnd2,xo2==16'h9999,carry2,dn2})
156 55 robfinch
        4'b0??0:        mo <= mo1[N*4-1:0];                                                     // not rounding, not denormalized
157
        4'b0??1:        mo <= mo1[N*4-1:0];                                                     // not rounding, denormalized
158
        4'b1000:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, number was normalized
159
        4'b1001:        mo <= rounded2[N*4-1: 0];                               // exponent didn't change, but number was denormalized
160
        4'b1010:        mo <= {4'h1,rounded2[N*4-1: 4]};        // exponent incremented (new MSD generated), number was normalized
161
        4'b1011:        mo <= rounded2[N*4-1:0];                                        // exponent incremented (new MSB generated), number was denormalized, number became normalized
162
        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
163 50 robfinch
        endcase
164
 
165
endmodule

powered by: WebSVN 2.1.0

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