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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpdivr2.v] - Rev 36

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

// ============================================================================
//        __
//   \\__/ o\    (C) 2006-2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
//	fpdivr2.v
//    Radix 2 floating point divider primitive
//
//
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
// ============================================================================
 
module fpdivr2(clk4x, ld, a, b, q, r, done, lzcnt);
parameter WID = 112;
parameter RADIX = 2;
localparam WID1 = WID;//((WID+2)/3)*3;    // make width a multiple of three
localparam DMSB = WID1-1;
input clk4x;
input ld;
input [WID1-1:0] a;
input [WID1-1:0] b;
output reg [WID1*2-1:0] q = 0;
output reg [WID1-1:0] r = 0;
output reg done = 1'b0;
output reg [7:0] lzcnt;
 
 
reg [8:0] cnt;				// iteration count
reg [WID1*2-1:0] qi = 0;
reg [DMSB+1:0] ri = 0; 
wire b0;
reg gotnz;					// got a non-zero bit
 
reg done1;
wire [7:0] maxcnt;
assign b0 = b <= ri;
wire [DMSB+1:0] r1 = b0 ? ri - b : ri;
assign maxcnt = WID1*2;
 
// Done pulse for external circuit. Must span over 1 1x clock so that it's
// recognized.
always @(posedge clk4x)
if (ld)
	done <= 1'b0;
else if (cnt==9'h1FE)
	done <= 1'b1;
else if (cnt==9'h1F7)
	done <= 1'b0;
 
// Internal done pulse
always @(posedge clk4x)
begin
	done1 <= 1'b0;
	if (ld)
		done1 <= 1'b0;
	else if (cnt==9'h1FF)
		done1 <= 1'b1;
end
 
always @(posedge clk4x)
if (ld)
	cnt <= maxcnt;
else if (cnt != 9'h1F7)
	cnt <= cnt - 8'd1;
 
always @(posedge clk4x)
if (ld)
	gotnz <= 1'b0;
else if (!cnt[8]) begin
	if (b0)
		gotnz <= 1'b1;
end
 
wire cnt81;
delay1 #(1) u1 (clk4x, 1'b1, cnt[8], cnt81);
 
always @(posedge clk4x)
if (ld)
	lzcnt <= 8'h00;
else if (!cnt81) begin
	if (b0==1'b0 && !gotnz)
		lzcnt <= lzcnt + 8'd1;
end
 
always @(posedge clk4x)
if (ld)
    qi <= {3'b0,a,{WID1{1'b0}}};
else if (!cnt81)
    qi[WID1*2-1:0] <= {qi[WID1*2-1-1:0],b0};
 
always @(posedge clk4x)
if (ld)
	ri <= 0;
else if (!cnt81)
    ri <= {r1[DMSB:0],qi[WID1*2-1]};
 
always @(posedge clk4x)
if (done1)
	q <= qi;
always @(posedge clk4x)
if (done1)
	r <= ri;
 
endmodule
 
 
 

Go to most recent revision | 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.