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

Subversion Repositories thor

[/] [thor/] [trunk/] [rtl/] [verilog/] [fpUnit/] [fpDiv.v] - Blame information for rev 21

Go to most recent revision | 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
        fpDiv.v
7
                - floating point divider
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 you do modify the code, please state the origin and
17
        note that you have modified the code.
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
        This multiplier/divider handles denormalized numbers.
39
        The output format is of an internal expanded representation
40
        in preparation to be fed into a normalization unit, then
41
        rounding. Basically, it's the same as the regular format
42
        except the mantissa is doubled in size, the leading two
43
        bits of which are assumed to be whole bits.
44
 
45
 
46
        Floating Point Multiplier / Divider
47
 
48
        Properties:
49
        +-inf * +-inf = -+inf   (this is handled by exOver)
50
        +-inf * 0     = QNaN
51
        +-0 / +-0         = QNaN
52
 
53
        Ref: Webpack8.2i Spartan3-4 xc3s1000-4ft256
54
        316 LUTS / 174 slices / 49.7 MHz
55
=============================================================== */
56
 
57
module fpDiv(clk, ce, ld, a, b, o, done, sign_exe, overflow, underflow);
58
 
59
parameter WID = 32;
60
localparam MSB = WID-1;
61
localparam EMSB = WID==80 ? 14 :
62
                  WID==64 ? 10 :
63
                                  WID==52 ? 10 :
64
                                  WID==48 ? 10 :
65
                                  WID==44 ? 10 :
66
                                  WID==42 ? 10 :
67
                                  WID==40 ?  9 :
68
                                  WID==32 ?  7 :
69
                                  WID==24 ?  6 : 4;
70
localparam FMSB = WID==80 ? 63 :
71
                  WID==64 ? 51 :
72
                                  WID==52 ? 39 :
73
                                  WID==48 ? 35 :
74
                                  WID==44 ? 31 :
75
                                  WID==42 ? 29 :
76
                                  WID==40 ? 28 :
77
                                  WID==32 ? 22 :
78
                                  WID==24 ? 15 : 9;
79
 
80
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
81
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
82
 
83
input clk;
84
input ce;
85
input ld;
86
input [MSB:0] a, b;
87
output [EX:0] o;
88
output done;
89
output sign_exe;
90
output overflow;
91
output underflow;
92
 
93
// registered outputs
94
reg sign_exe;
95
reg inf;
96
reg     overflow;
97
reg     underflow;
98
 
99
reg so;
100
reg [EMSB:0] xo;
101
reg [FX:0] mo;
102
assign o = {so,xo,mo};
103
 
104
// constants
105
wire [EMSB:0] infXp = {EMSB+1{1'b1}};    // infinite / NaN - all ones
106
// The following is the value for an exponent of zero, with the offset
107
// eg. 8'h7f for eight bit exponent, 11'h7ff for eleven bit exponent, etc.
108
wire [EMSB:0] bias = {1'b0,{EMSB{1'b1}}};        //2^0 exponent
109
// The following is a template for a quiet nan. (MSB=1)
110
wire [FMSB:0] qNaN  = {1'b1,{FMSB{1'b0}}};
111
 
112
// variables
113
wire [EMSB+2:0] ex1;     // sum of exponents
114
wire [FX:0] divo;
115
 
116
// Operands
117
wire sa, sb;                    // sign bit
118
wire [EMSB:0] xa, xb;    // exponent bits
119
wire [FMSB+1:0] fracta, fractb;
120
wire a_dn, b_dn;                        // a/b is denormalized
121
wire az, bz;
122
wire aInf, bInf;
123
 
124
 
125
// -----------------------------------------------------------
126
// - decode the input operands
127
// - derive basic information
128
// - calculate exponent
129
// - calculate fraction
130
// -----------------------------------------------------------
131
 
132
fpDecomp #(WID) u1a (.i(a), .sgn(sa), .exp(xa), .fract(fracta), .xz(a_dn), .vz(az), .inf(aInf) );
133
fpDecomp #(WID) u1b (.i(b), .sgn(sb), .exp(xb), .fract(fractb), .xz(b_dn), .vz(bz), .inf(bInf) );
134
 
135
// Compute the exponent.
136
// - correct the exponent for denormalized operands
137
// - adjust the difference by the bias (add 127)
138
// - also factor in the different decimal position for division
139
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB-1;
140
 
141
// check for exponent underflow/overflow
142
wire under = ex1[EMSB+2];       // MSB set = negative exponent
143
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
144
 
145
// Perform divide
146
// could take either 1 or 16 clock cycles
147
fpdivr8 #(WID) u2 (.clk(clk), .ld(ld), .a(fracta), .b(fractb), .q(divo), .r(), .done(done));
148
 
149
// determine when a NaN is output
150
wire qNaNOut = (az&bz)|(aInf&bInf);
151
 
152
always @(posedge clk)
153
        if (ce) begin
154
                if (done) begin
155
                        casex({qNaNOut,bInf,bz})
156
                        3'b1xx:         xo = infXp;     // NaN exponent value
157
                        3'bx1x:         xo = 0;          // divide by inf
158
                        3'bxx1:         xo = infXp;     // divide by zero
159
                        default:        xo = ex1;               // normal or underflow: passthru neg. exp. for normalization
160
                        endcase
161
 
162
                        casex({qNaNOut,bInf,bz})
163
                        3'b1xx:         mo = {1'b0,qNaN[FMSB:0]|{aInf,1'b0}|{az,bz},{FMSB+1{1'b0}}};
164
                        3'bx1x:         mo = 0;  // div by inf
165
                        3'bxx1:         mo = 0;  // div by zero
166
                        default:        mo = divo;              // plain div
167
                        endcase
168
 
169
                        so              = sa ^ sb;
170
                        sign_exe        = sa & sb;
171
                        overflow        = over;
172
                        underflow       = under;
173
                end
174
        end
175
 
176
endmodule

powered by: WebSVN 2.1.0

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