URL
https://opencores.org/ocsvn/ft816float/ft816float/trunk
Subversion Repositories ft816float
[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [dfdiv.sv] - Rev 84
Go to most recent revision | Compare with Previous | Blame | View Log
// ============================================================================// __// \\__/ o\ (C) 2006-2022 Robert Finch, Waterloo// \ __ / All rights reserved.// \/_// robfinch<remove>@finitron.ca// ||//// dfdiv.v// Decimal Float divider primitive//// BSD 3-Clause License// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// 1. Redistributions of source code must retain the above copyright notice, this// list of conditions and the following disclaimer.//// 2. Redistributions in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.//// 3. Neither the name of the copyright holder nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.//// ============================================================================module dfdiv(clk, ld, a, b, q, r, done, lzcnt);parameter N=33;localparam FPWID = N*4;parameter RADIX = 10;localparam FPWID1 = FPWID;//((FPWID+2)/3)*3; // make FPWIDth a multiple of threelocalparam DMSB = FPWID1-1;input clk;input ld;input [FPWID-1:0] a;input [FPWID-1:0] b;output reg [FPWID*2-1:0] q;output reg [FPWID-1:0] r;output reg done;output reg [7:0] lzcnt; // Leading zero digit count as a BCD numberreg [1:0] st;parameter IDLE = 2'd0;parameter SUBN = 2'd1;parameter DONE = 2'd2;reg [3:0] cnt; // iteration countwire [3:0] cntm1 = cnt;//cnt==4'd0 ? 4'd9 : cnt-1'd1;reg [7:0] dcnt; // digit countreg [15:0] clkcnt;reg [5:0] digcnt;reg [FPWID*2-1:0] qi;reg [FPWID+3:0] ri;reg [FPWID-1:0] bi;wire sgn;wire [FPWID+3:0] dif;reg gotnz; // got a non-zero digitgenerate begin : gSubBCDSubtract #(.N(N+1)) ubcds1(.clk(clk),.a(ri),.b({4'b0,bi}),.o(dif),.sgn(sgn));endendgeneratereg nz;reg [N-1:0] zc;genvar g;generate begin : glzcntfor (g = N-1; g >= 0; g = g - 1)always_combzc[g] = qi[g*4+3+N*4:g*4+N*4]==0;endendgenerateinteger n;always_combbeginnz = 1'b0;lzcnt = 'd0;for (n = N-1; n >= 0; n = n - 1)beginnz = nz | ~zc[n];if (!nz)lzcnt = lzcnt + 1;endendalways @(posedge clk)begincase(st)IDLE:beginqi <= 'd0;ri <= 'd0;endSUBN:begindigcnt <= digcnt - 1'd1;if (digcnt=='d0) beginclkcnt <= clkcnt + 1'd1;digcnt <= 6'd10;if (bi > ri) beginri <= {ri,qi[FPWID*2-1:FPWID*2-4]};qi <= {qi[FPWID*2-5:0],cnt};cnt <= 4'd0;dcnt <= dcnt - 1'd1;if (dcnt=='d0)st <= DONE;endelse beginif (clkcnt > 600 && 0) beginri <= {ri,qi[FPWID*2-1:FPWID*2-4]};qi <= {qi[FPWID*2-5:0],cntm1};cnt <= 4'd0;dcnt <= dcnt - 1'd1;if (dcnt==6'd0)st <= DONE;endelsebeginri <= dif;//N[0] ? dif : dif[FPWID+4-1:4];cnt <= cnt + 1'd1;endendendendDONE:beginq <= qi;r <= ri;done <= 1'b1;enddefault:st <= IDLE;endcaseif (ld) beginclkcnt <= 10'd0;cnt <= 4'd0;digcnt <= 6'd10;dcnt <= $ceil(FPWID*2/4);qi <= {a,{FPWID{1'd0}}};ri <= {FPWID{1'd0}};bi <= b;st <= SUBN;done <= 1'b0;endendendmodulemodule dfdiv_tb();reg clk;reg ld;reg [135:0] a, b;wire [271:0] q;wire [135:0] r;wire [7:0] lzcnt;initial beginclk = 1'b0;ld = 1'b0;a = 136'h50_00000000_00000000_00000000_00000000;b = 136'h50_00000000_00000000_00000000_00000000;#20 ld = 1'b1;#40 ld = 1'b0;endalways #5 clk = ~clk;dfdiv #(.N(34)) u1 (.clk(clk),.ld(ld),.a(a),.b(b),.q(q),.r(r),.done(done),.lzcnt(lzcnt));endmodule
Go to most recent revision | Compare with Previous | Blame | View Log
