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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [isqrt.v] - Blame information for rev 13

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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