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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [dfdiv.sv] - Blame information for rev 86

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 82 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2006-2022  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//      dfdiv.v
9
//    Decimal Float divider primitive
10
//
11
// BSD 3-Clause License
12
// Redistribution and use in source and binary forms, with or without
13
// modification, are permitted provided that the following conditions are met:
14
//
15
// 1. Redistributions of source code must retain the above copyright notice, this
16
//    list of conditions and the following disclaimer.
17
//
18
// 2. Redistributions in binary form must reproduce the above copyright notice,
19
//    this list of conditions and the following disclaimer in the documentation
20
//    and/or other materials provided with the distribution.
21
//
22
// 3. Neither the name of the copyright holder nor the names of its
23
//    contributors may be used to endorse or promote products derived from
24
//    this software without specific prior written permission.
25
//
26
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
//
37
// ============================================================================
38
 
39
module dfdiv(clk, ld, a, b, q, r, done, lzcnt);
40
parameter N=33;
41
localparam FPWID = N*4;
42
parameter RADIX = 10;
43
localparam FPWID1 = FPWID;//((FPWID+2)/3)*3;    // make FPWIDth a multiple of three
44
localparam DMSB = FPWID1-1;
45
input clk;
46
input ld;
47
input [FPWID-1:0] a;
48
input [FPWID-1:0] b;
49
output reg [FPWID*2-1:0] q;
50
output reg [FPWID-1:0] r;
51
output reg done;
52
output reg [7:0] lzcnt; // Leading zero digit count as a BCD number
53
 
54
 
55
reg [1:0] st;
56
parameter IDLE = 2'd0;
57
parameter SUBN = 2'd1;
58
parameter DONE = 2'd2;
59
 
60
reg [3:0] cnt;                          // iteration count
61
wire [3:0] cntm1 = cnt;//cnt==4'd0 ? 4'd9 : cnt-1'd1;
62
reg [7:0] dcnt;                         // digit count
63
reg [15:0] clkcnt;
64
reg [5:0] digcnt;
65
reg [FPWID*2-1:0] qi;
66
reg [FPWID+3:0] ri;
67
reg [FPWID-1:0] bi;
68
wire sgn;
69 84 robfinch
wire [FPWID+3:0] dif;
70 82 robfinch
reg gotnz;                                      // got a non-zero digit
71
 
72
generate begin : gSub
73 84 robfinch
BCDSubtract #(.N(N+1)) ubcds1
74 82 robfinch
(
75
        .clk(clk),
76
        .a(ri),
77 84 robfinch
        .b({4'b0,bi}),
78 82 robfinch
        .o(dif),
79
        .sgn(sgn)
80
);
81
end
82
endgenerate
83
 
84
reg nz;
85 86 robfinch
reg [N*2-1:0] zc;
86 82 robfinch
genvar g;
87
generate begin : glzcnt
88 86 robfinch
        for (g = N*2-1; g >= 0; g = g - 1)
89 82 robfinch
        always_comb
90 86 robfinch
                zc[g] = qi[g*4+3:g*4]==0;
91 82 robfinch
end
92
endgenerate
93
 
94
integer n;
95
always_comb
96
begin
97
        nz = 1'b0;
98
        lzcnt = 'd0;
99 86 robfinch
        for (n = N*2-1; n >= 0; n = n - 1)
100 82 robfinch
        begin
101
                nz = nz | ~zc[n];
102
                if (!nz)
103
                        lzcnt = lzcnt + 1;
104
        end
105
end
106
 
107
always @(posedge clk)
108
begin
109
case(st)
110
IDLE:
111
        begin
112
                qi <= 'd0;
113
                ri <= 'd0;
114
        end
115
SUBN:
116
        begin
117
                digcnt <= digcnt - 1'd1;
118
                if (digcnt=='d0) begin
119
                        clkcnt <= clkcnt + 1'd1;
120
                        digcnt <= 6'd10;
121 84 robfinch
                        if (bi > ri) begin
122 82 robfinch
                                ri <= {ri,qi[FPWID*2-1:FPWID*2-4]};
123
                                qi <= {qi[FPWID*2-5:0],cnt};
124
                                cnt <= 4'd0;
125
                                dcnt <= dcnt - 1'd1;
126
                                if (dcnt=='d0)
127
                                        st <= DONE;
128
                        end
129
                        else begin
130 84 robfinch
                                if (clkcnt > 600 && 0) begin
131 82 robfinch
                                        ri <= {ri,qi[FPWID*2-1:FPWID*2-4]};
132
                                        qi <= {qi[FPWID*2-5:0],cntm1};
133
                                        cnt <= 4'd0;
134
                                        dcnt <= dcnt - 1'd1;
135
                                        if (dcnt==6'd0)
136
                                                st <= DONE;
137
                                end
138
                                else
139
                                begin
140 86 robfinch
                                        ri <= dif;
141 82 robfinch
                                        cnt <= cnt + 1'd1;
142
                                end
143
                        end
144
                end
145
        end
146
DONE:
147
        begin
148
                q <= qi;
149
                r <= ri;
150
                done <= 1'b1;
151
        end
152
default:
153
        st <= IDLE;
154
endcase
155
if (ld) begin
156
        clkcnt <= 10'd0;
157
        cnt <= 4'd0;
158
        digcnt <= 6'd10;
159
        dcnt <= $ceil(FPWID*2/4);
160
        qi <= {a,{FPWID{1'd0}}};
161
        ri <= {FPWID{1'd0}};
162
        bi <= b;
163
        st <= SUBN;
164
        done <= 1'b0;
165
end
166
end
167
 
168
endmodule
169
 
170
module dfdiv_tb();
171
 
172
reg clk;
173
reg ld;
174
reg [135:0] a, b;
175
wire [271:0] q;
176
wire [135:0] r;
177
wire [7:0] lzcnt;
178
 
179
initial begin
180
        clk = 1'b0;
181
        ld = 1'b0;
182
        a = 136'h50_00000000_00000000_00000000_00000000;
183
        b = 136'h50_00000000_00000000_00000000_00000000;
184
        #20 ld = 1'b1;
185
        #40 ld = 1'b0;
186
end
187
 
188
always #5 clk = ~clk;
189
 
190
dfdiv #(.N(34)) u1 (
191
        .clk(clk),
192
        .ld(ld),
193
        .a(a),
194
        .b(b),
195
        .q(q),
196
        .r(r),
197
        .done(done),
198
        .lzcnt(lzcnt)
199
);
200
endmodule

powered by: WebSVN 2.1.0

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