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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [dfisqrt.v] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2010-2020  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
//      dfisqrt.v
10
//      - integer square root
11
//  - uses the standard long form calc.
12
//      - geared towards use in an decimal floating point unit
13
//      - calculates to WID fractional precision (double width output)
14
//
15
//
16
// BSD 3-Clause License
17
// Redistribution and use in source and binary forms, with or without
18
// modification, are permitted provided that the following conditions are met:
19
//
20
// 1. Redistributions of source code must retain the above copyright notice, this
21
//    list of conditions and the following disclaimer.
22
//
23
// 2. Redistributions in binary form must reproduce the above copyright notice,
24
//    this list of conditions and the following disclaimer in the documentation
25
//    and/or other materials provided with the distribution.
26
//
27
// 3. Neither the name of the copyright holder nor the names of its
28
//    contributors may be used to endorse or promote products derived from
29
//    this software without specific prior written permission.
30
//
31
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
35
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41
//                                                                          
42
// ============================================================================
43
 
44
module dfisqrt(rst, clk, ce, ld, a, o, done);
45
parameter N=34;
46
parameter WID = N*4;
47
localparam MSB = WID-1;
48
input rst;
49
input clk;
50
input ce;
51
input ld;
52
input [MSB:0] a;
53
output reg [WID*2-1:0] o;
54
output reg done;
55
 
56
reg [3:0] state;
57
parameter SKIPLZ = 4'd1;
58
parameter A0 = 4'd2;
59
parameter S3 = 4'd3;
60
parameter INCJ = 4'd4;
61
parameter DONE = 4'd5;
62
parameter S1 = 4'd6;
63
parameter S4 = 4'd7;
64
parameter S2 = 4'd8;
65
 
66
reg [3:0] tbl [0:255];
67
reg [7:0] tbl5 [0:9];
68
reg [7:0] sqra [0:9];
69
 
70
initial begin
71
        sqra[0] = 8'h00;
72
        sqra[1] = 8'h01;
73
        sqra[2] = 8'h04;
74
        sqra[3] = 8'h09;
75
        sqra[4] = 8'h16;
76
        sqra[5] = 8'h25;
77
        sqra[6] = 8'h36;
78
        sqra[7] = 8'h49;
79
        sqra[8] = 8'h64;
80
        sqra[9] = 8'h81;
81
end
82
 
83
genvar g;
84
generate begin
85
        for (g = 0; g < 256; g = g + 1)
86
                initial begin
87
                        if (g >= 8'h81)
88
                                tbl[g] = 4'h9;
89
                        else if (g >= 8'h64)
90
                                tbl[g] = 4'h8;
91
                        else if (g >= 8'h49)
92
                                tbl[g] = 4'h7;
93
                        else if (g >= 8'h36)
94
                                tbl[g] = 4'h6;
95
                        else if (g >= 8'h25)
96
                                tbl[g] = 4'h5;
97
                        else if (g >= 8'h16)
98
                                tbl[g] = 4'h4;
99
                        else if (g >= 8'h09)
100
                                tbl[g] = 4'd3;
101
                        else if (g >= 8'h04)
102
                                tbl[g] = 4'h2;
103
                        else if (g >= 8'h01)
104
                                tbl[g] = 4'h1;
105
                        else
106
                                tbl[g] = 4'h0;
107
                end
108
end
109
endgenerate
110
 
111
initial begin
112
        tbl5[0] = 8'h05;
113
        tbl5[1] = 8'h15;
114
        tbl5[2] = 8'h25;
115
        tbl5[3] = 8'h35;
116
        tbl5[4] = 8'h45;
117
        tbl5[5] = 8'h55;
118
        tbl5[6] = 8'h65;
119
        tbl5[7] = 8'h75;
120
        tbl5[8] = 8'h85;
121
        tbl5[9] = 8'h95;
122
end
123
 
124
 
125
reg [7:0] dcnt;
126
reg [7:0] j;
127
reg [N*2*4-1:0] b;
128
reg [N*4*2-1:0] ii;
129
wire [N*4*2-1:0] firstRa;
130
reg [N*4*2-1+4:0] ai, Rbx5;
131
wire [(N*2+1)*4-1:0] Rax2, Rax4, Rax5i, newRax5a;
132
reg [(N*2+1)*4-1:0] Rax5, pRax5, newRax5;
133
wire tooBig;
134
 
135
BCDAddN #(.N(N*2+1)) ua1 (.ci(1'b0), .a({4'h0,firstRa}), .b({4'h0,firstRa}), .o(Rax2), .co());
136
BCDAddN #(.N(N*2+1)) ua2 (.ci(1'b0), .a(Rax2), .b(Rax2), .o(Rax4), .co());
137
BCDAddN #(.N(N*2+1)) ua3 (.ci(1'b0), .a({4'h0,firstRa}), .b(Rax4), .o(Rax5i), .co());
138
 
139
BCDSubN #(.N(N*2+1)) ua4 (.ci(1'b0), .a(Rax5), .b(Rbx5), .o(newRax5a), .co(tooBig));
140
 
141
 
142
wire [3:0] a0 = tbl[ii[N*4*2-1:N*4*2-8]];
143
wire [7:0] sqra00 = sqra[a0];
144
wire [N*2*4+3:0] srqa0 = {4'h0,sqra00,{N*2*4-8{1'b0}}};
145
 
146
BCDSubN #(.N(N*2)) ua5 (.ci(1'b0), .a(ii), .b(srqa0), .o(firstRa), .co());
147
 
148
wire [WID*2-1:0] tbl5x = {tbl5[b[3:0]],{(N*2-3)*4{1'b0}}};
149
wire [WID*2-1:0] tbl5s = tbl5x >> {j,2'h0};
150
 
151
wire [N*2*4-1:0] sum_ai;
152
BCDAddN #(.N(N*2)) ua6 (.ci(1'b0), .a(ai), .b(tbl5s), .o(sum_ai), .co());
153
 
154
always @(posedge clk)
155
begin
156
case(state)
157
SKIPLZ:
158
        begin
159
                Rax5 <= {N*2*4+4{1'd0}};
160
                Rbx5 <= {N*2*4+4{1'd0}};
161
                if (ii[N*4*2-1:N*4*2-8]==8'h00) begin
162
                        ii <= {ii[N*4*2-9:0],8'h00};
163
                        dcnt <= dcnt - 8'd2;
164
                        if (dcnt==8'h00) begin
165
                                o <= {WID*2{1'b0}};
166
                                state <= DONE;
167
                        end
168
                end
169
                else
170
                        state <= A0;
171
        end
172
        // Get the first digit of the square root.
173
A0:
174
        begin
175
                b <= 4'd0;
176
                ai <= {4'd0,a0,{(N*2-2)*4{1'b0}}};
177
                state <= S1;
178
        end
179
        // Set initial Ra5
180
S1:
181
        begin
182
                Rax5 <= Rax5i;
183
                Rbx5 <= {4'h0,sum_ai};
184
                pRax5 <= Rax5i;
185
                state <= S2;
186
        end
187
S2:
188
        begin
189
                newRax5 <= newRax5a;
190
                if (tooBig) begin
191
                        Rax5 <= {Rax5,4'h0};
192
                        ai <= ai | (b << (N*2-j)*4-8);
193
                        state <= INCJ;
194
                end
195
                else begin
196
                        b <= b + 1'd1;
197
                        state <= S3;
198
                end
199
        end
200
S3:
201
        begin
202
                pRax5 <= Rax5;
203
                Rax5 <= newRax5;
204
                Rbx5 <= {4'h0,sum_ai};
205
                state <= S2;
206
        end
207
INCJ:
208
        begin
209
                b <= 4'd0;
210
                j <= j + 1'd1;
211
                dcnt <= dcnt - 1'd1;
212
                if (dcnt==0) begin
213
                        state <= DONE;
214
                        o <= ai;
215
                end
216
                else
217
                        state <= S4;
218
        end
219
S4:
220
        begin
221
                Rbx5 <= {4'h0,sum_ai};
222
                state <= S2;
223
        end
224
DONE:
225
        begin
226
                done <= 1'b1;
227
        end
228
endcase
229
if (ld) begin
230
        state <= SKIPLZ;
231
        dcnt <= N*2;
232
        j <= 8'd1;
233
        b <= 4'd0;
234
        ii <= {a,{N*4{1'b0}}};
235
        done <= 1'b0;
236
end
237
end
238
 
239
endmodule
240
 
241
 
242
module dfisqrt_tb();
243
parameter N=34;
244
 
245
reg clk;
246
reg rst;
247
reg [N*4-1:0] a;
248
wire [N*4*2-1:0] o;
249
reg ld;
250
wire done;
251
reg [7:0] state;
252
 
253
initial begin
254
        clk = 1;
255
        rst = 0;
256
        #100 rst = 1;
257
        #100 rst = 0;
258
end
259
 
260
always #10 clk = ~clk;  //  50 MHz
261
 
262
always @(posedge clk)
263
if (rst) begin
264
        state <= 8'd0;
265
        a <= 64'h987654321;
266
end
267
else
268
begin
269
ld <= 1'b0;
270
case(state)
271
8'd0:
272
        begin
273
                a <= 64'h987654321;
274
                ld <= 1'b1;
275
                state <= 8'd1;
276
        end
277
8'd1:
278
        if (done) begin
279
                $display("i=%h o=%h", a, o);
280
        end
281
endcase
282
end
283
 
284
dfisqrt #(.N(N)) u1 (.rst(rst), .clk(clk), .ce(1'b1), .ld(ld), .a(a), .o(o), .done(done));
285
 
286
endmodule
287
 
288
 

powered by: WebSVN 2.1.0

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