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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [fpUnit/] [isqrt.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 51 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2010-2018  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
//      isqrt.v
10
//      - integer square root
11
//  - uses the standard long form calc.
12
//      - geared towards use in an floating point unit
13
//      - calculates to WID fractional precision (double width output)
14
//
15
//
16
// This source file is free software: you can redistribute it and/or modify 
17
// it under the terms of the GNU Lesser General Public License as published 
18
// by the Free Software Foundation, either version 3 of the License, or     
19
// (at your option) any later version.                                      
20
//                                                                          
21
// This source file is distributed in the hope that it will be useful,      
22
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
23
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
24
// GNU General Public License for more details.                             
25
//                                                                          
26
// You should have received a copy of the GNU General Public License        
27
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
28
//                                                                          
29
// ============================================================================
30
 
31
module isqrt(rst, clk, ce, ld, a, o, done);
32
parameter WID = 32;
33
localparam MSB = WID-1;
34
parameter IDLE=3'd0;
35
parameter CALC=3'd1;
36
parameter DONE=3'd2;
37
input rst;
38
input clk;
39
input ce;
40
input ld;
41
input [MSB:0] a;
42
output [WID*2-1:0] o;
43
output done;
44
 
45
reg [2:0] state;
46
reg [WID*2:0] root;
47
wire [WID*2-1:0] testDiv;
48
reg [WID*2-1:0] remLo;
49
reg [WID*2-1:0] remHi;
50
 
51
wire cnt_done;
52
assign testDiv = {root[WID*2-2:0],1'b1};
53
wire [WID*2-1:0] remHiShift = {remHi[WID*2-3:0],remLo[WID*2-1:WID*2-2]};
54
wire doesGoInto = remHiShift >= testDiv;
55
assign o = root[WID*2:1];
56
 
57
// Iteration counter
58
reg [7:0] cnt;
59
 
60
always @(posedge clk)
61
if (rst) begin
62
        cnt <= WID*2;
63
        remLo <= {WID{1'b0}};
64
        remHi <= {WID{1'b0}};
65
        root <= {WID{1'b0}};
66
        state <= IDLE;
67
end
68
else if (ce) begin
69
        if (!cnt_done)
70
                cnt <= cnt + 8'd1;
71
case(state)
72
IDLE:
73
        if (ld) begin
74
                cnt <= 8'd0;
75
                state <= CALC;
76
                remLo <= {a,32'h0};
77
                remHi <= {WID{1'b0}};
78
                root <= {WID{1'b0}};
79
        end
80
CALC:
81
        if (!cnt_done) begin
82
                // Shift the remainder low
83
                remLo <= {remLo[WID*2-3:0],2'd0};
84
                // Shift the remainder high
85
                remHi <= doesGoInto ? remHiShift - testDiv: remHiShift;
86
                // Shift the root
87
                root <= {root+doesGoInto,1'b0}; // root * 2 + 1/0
88
        end
89
        else begin
90
                cnt <= 8'h00;
91
                state <= DONE;
92
        end
93
DONE:
94
        begin
95
                cnt <= cnt + 8'd1;
96
                if (cnt == 8'd6)
97
                        state <= IDLE;
98
        end
99
endcase
100
end
101
assign cnt_done = (cnt==WID);
102
assign done = state==DONE;
103
 
104
endmodule
105
 
106
 
107
module isqrt_tb();
108
 
109
reg clk;
110
reg rst;
111
reg [31:0] a;
112
wire [63:0] o;
113
reg ld;
114
wire done;
115
reg [7:0] state;
116
 
117
initial begin
118
        clk = 1;
119
        rst = 0;
120
        #100 rst = 1;
121
        #100 rst = 0;
122
end
123
 
124
always #10 clk = ~clk;  //  50 MHz
125
 
126
always @(posedge clk)
127
if (rst) begin
128
        state <= 8'd0;
129
        a <= 32'h912345;
130
end
131
else
132
begin
133
ld <= 1'b0;
134
case(state)
135
8'd0:
136
        begin
137
                a <= 32'h9123456;
138
                ld <= 1'b1;
139
                state <= 8'd1;
140
        end
141
8'd1:
142
        if (done) begin
143
                $display("i=%h o=%h", a, o);
144
        end
145
endcase
146
end
147
 
148
isqrt #(32) u1 (.rst(rst), .clk(clk), .ce(1'b1), .ld(ld), .a(a), .o(o), .done(done));
149
 
150
endmodule
151
 
152
 

powered by: WebSVN 2.1.0

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