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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [rtl/] [verilog/] [lib/] [math/] [isqrt.v] - Rev 3

Compare with Previous | Blame | View Log

// ============================================================================
//  isqrt.v
//  - take the integer square root
//
//
//	2010,2011  Robert Finch
//	robfinch>remove<@sympatico.ca
//
//
//  This source code is available for evaluation and validation purposes
//  only. This copyright statement and disclaimer must remain present in
//  the file.
//
//
//	NO WARRANTY.
//  THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
//  EXPRESS OR IMPLIED. The user must assume the entire risk of using the
//  Work.
//
//  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
//  INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
//  THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
//
//  IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
//  IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
//  REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
//  LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
//  AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
//  LOSSES RELATING TO SUCH UNAUTHORIZED USE.
//
//
//	Verilog 1995
//	Webpack 13.i  xc3s1200e-4fg320
//	94 slices / 172 LUTs / 141.906 MHz
//  101 ff's
//
// ============================================================================
 
module isqrt(rst, clk, ce, ld, a, o, done);
parameter WID = 32;
localparam MSB = WID-1;
parameter IDLE=3'd0;
parameter CALC=3'd1;
parameter DONE=3'd2;
input rst;
input clk;
input ce;
input ld;
input [MSB:0] a;
output [MSB:0] o;
output done;
 
reg [2:0] state;
reg [MSB:0] root;
wire [MSB:0] testDiv;
reg [MSB:0] remLo;
reg [MSB:0] remHi;
 
wire cnt_done;
assign testDiv = {root,1'b1};
wire [MSB:0] remHiShift = {remHi[MSB-2:0],remLo[MSB:MSB-1]};
wire doesGoInto = remHiShift >= testDiv;
assign o = root[MSB:1];
 
// Iteration counter
reg [7:0] cnt;
 
always @(posedge clk)
if (rst) begin
	cnt <= WID>>1;
	remLo <= {WID{1'b0}};
	remHi <= {WID{1'b0}};
	root <= {WID{1'b0}};
	state <= IDLE;
end
else if (ce) begin
	if (!cnt_done)
		cnt <= cnt + 8'd1;
case(state)
IDLE:
	if (ld) begin
		cnt <= 8'd0;
		state <= CALC;
		remLo <= a;
		remHi <= {WID{1'b0}};
		root <= {WID{1'b0}};
	end
CALC:
	if (!cnt_done) begin
		// Shift the remainder low
		remLo <= {remLo[MSB-2:0],2'd0};
		// Shift the remainder high
		remHi <= doesGoInto ? remHiShift - testDiv: remHiShift;
		// Shift the root
		root <= {root+doesGoInto,1'b0};	// root * 2 + 1/0
	end
	else
		state <= DONE;
DONE:
	begin
		state <= IDLE;
	end
endcase
end
assign cnt_done = (cnt==WID>>1);
assign done = state==DONE;
 
endmodule
 
 
module isqrt_tb();
 
reg clk;
reg rst;
reg [31:0] a;
wire [31:0] o;
reg ld;
wire done;
reg [7:0] state;
 
initial begin
	clk = 1;
	rst = 0;
	#100 rst = 1;
	#100 rst = 0;
end
 
always #10 clk = ~clk;	//  50 MHz
 
always @(posedge clk)
if (rst) begin
	state <= 8'd0;
	a <= 32'h123456;
end
else
begin
ld <= 1'b0;
case(state)
8'd0:
	begin	
		a <= 32'd1;
		ld <= 1'b1;
		state <= 8'd1;
	end
8'd1:
	if (done) begin
		$display("i=%h o=%h", a, o);
	end
endcase
end
 
isqrt #(32) u1 (.rst(rst), .clk(clk), .ce(1'b1), .ld(ld), .a(a), .o(o), .done(done));
 
endmodule
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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