Attention

This documentation is a work in progress. Expect to see errors and unfinished things.

isqrt Source File

 1`timescale 1ns / 1ns
 2
 3//
 4// Simple-minded integer square root
 5// Result is truncated not rounded
 6//
 7// General purpose with the caveat that XWIDTH should be greater than 3.
 8// (X_WIDTH+1)/2 + 1 cycles per operation, non-pipelined.
 9// Asserting en when computation is in progress will
10// cancel the computation and start another.
11//
12// With XWIDTH=32, synthesizable to 110 MHz on Spartan3-5.
13//
14// W. Eric Norum, Lawrence Berkeley National Laboratory
15//
16
17module isqrt #(
18    parameter X_WIDTH = 32
19) (
20    input                             clk,
21    input               [X_WIDTH-1:0] x,
22    input                             en,
23    output wire [((X_WIDTH+1)/2)-1:0] y,
24    output reg                        dav = 0
25);
26
27localparam Y_WIDTH = (X_WIDTH+1) / 2;
28wire [X_WIDTH:0] xPad = {1'b0, x};
29wire [(2*Y_WIDTH)-1:0] xInit = xPad[(2*Y_WIDTH)-1:0];
30
31reg  [(2*Y_WIDTH)-1:0]  op = 0, pw4 = 0, res = 0;
32assign y = res[Y_WIDTH-1:0];
33
34reg busy = 0;
35
36always @(posedge clk)
37begin
38    if (en) begin
39        //
40        // op = x  (pad if X_WIDTH is odd)
41        // res = 0
42        // pw4 = highest power of 4 less than largest X
43        //
44        op <= xInit;
45        res <= 0;
46        pw4 <= {2'b01, {Y_WIDTH-1{2'b0}}};
47        dav <= 0;
48        busy <= 1;
49    end else if (busy) begin
50        //
51        // while (pw4 != 0) {
52        //     if (op >= res + pw4) {
53        //         op = op - (res + pw4);
54        //         res = res +  2 * pw4;
55        //     }
56        //     res >>= 1;
57        //     pw4 >>= 2;
58        // }
59        //
60        if (op >= (res + pw4)) begin
61            op <= op - (res + pw4);
62            res <= (res >> 1) + pw4;
63        end else begin
64            res <= (res >> 1);
65        end
66        pw4 <= (pw4 >> 2);
67        if (pw4[0]) begin
68            dav <= 1;
69            busy <= 0;
70        end
71    end else begin
72        dav <= 0;
73    end
74end
75endmodule