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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpdivr2.v] - Diff between revs 6 and 26

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 6 Rev 26
Line 1... Line 1...
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2006-2016  Robert Finch, Stratford
//   \\__/ o\    (C) 2006-2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     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 
// 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 
// 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     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
Line 16... Line 20...
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//
//
//      fpdivr2.v
 
//  Radix 2 floating point divider primitive
 
//      
 
// ============================================================================
// ============================================================================
//
 
module fpdivr2
 
#(      parameter WID = 24 )
 
(
 
        input clk,
 
        input ld,
 
        input [WID-1:0] a,
 
        input [WID-1:0] b,
 
        output reg [WID*2-1:0] q,
 
        output [WID-1:0] r,
 
        output done
 
);
 
        localparam DMSB = WID-1;
 
 
 
        reg [DMSB:0] rx [2:0];            // remainder holds
 
        reg [DMSB:0] rxx;
 
        reg [7:0] cnt;                           // iteration count
 
        wire [DMSB:0] sdq;
 
        wire [DMSB:0] sdr;
 
        wire sdval = 1'b0;
 
        wire sdbz;
 
  reg willGo0;
 
 
 
        //specialCaseDivider #(WID) u1 (.a(a), .b(b), .q(sdq), .r(sdr), .val(sdval), .dbz(sdbz) );
 
 
 
  initial begin
module fpdivr2(clk4x, ld, a, b, q, r, done, lzcnt);
    rx[0] = 0;
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
  end
 
 
        always @(posedge clk)
always @(posedge clk4x)
                if (ld)
                if (ld)
                        cnt <= sdval ? 8'b10000000 : WID*2-2;
        cnt <= maxcnt;
                else if (!done)
else if (cnt != 9'h1F7)
                        cnt <= cnt - 1;
        cnt <= cnt - 8'd1;
 
 
 
always @(posedge clk4x)
        always @(posedge clk)
if (ld)
                if (ld) begin
        gotnz <= 1'b0;
                        rxx <= 0;
else if (!cnt[8]) begin
                        if (sdval)
        if (b0)
                                q <= {sdq,{WID{1'b0}}};
                gotnz <= 1'b1;
                        else
 
                                q <= {a,{WID{1'b0}}};
 
                end
 
                else if (!done) begin
 
                  willGo0 = {rxx  ,q[WID*2-1  ]} > b;
 
      rx[0] = willGo0 ? {rxx  ,q[WID*2-1  ]} - b : {rxx  ,q[WID*2-1  ]};
 
                        q[WID*2-1:1] <= q[WID*2-1-1:0];
 
                        q[0] <= willGo0;
 
                        rxx <= rx[0];
 
                end
                end
 
 
        // correct remainder
wire cnt81;
        assign r = sdval ? sdr : rx[2][DMSB] ? rx[2] + b : rx[2];
delay1 #(1) u1 (clk4x, 1'b1, cnt[8], cnt81);
        assign done = cnt[7];
 
 
 
endmodule
 
 
 
/*
 
module fpdivr2_tb();
 
 
 
        reg rst;
always @(posedge clk4x)
        reg clk;
if (ld)
        reg ld;
        lzcnt <= 8'h00;
        reg [6:0] cnt;
else if (!cnt81) begin
 
        if (b0==1'b0 && !gotnz)
        wire ce = 1'b1;
                lzcnt <= lzcnt + 8'd1;
        wire [23:0] a = 24'h0_4000;
end
        wire [23:0] b = 24'd101;
 
        wire [45:0] q;
 
        wire [23:0] r;
 
        wire done;
 
 
 
        initial begin
 
                clk = 1;
 
                rst = 0;
 
                #100 rst = 1;
 
                #100 rst = 0;
 
        end
 
 
 
        always #20 clk = ~clk;  //  25 MHz
 
 
 
        always @(posedge clk)
 
                if (rst)
 
                        cnt <= 0;
 
                else begin
 
                        ld <= 0;
 
                        cnt <= cnt + 1;
 
                        if (cnt == 3)
 
                                ld <= 1;
 
                        $display("ld=%b q=%h r=%h done=%b", ld, q, r, done);
 
                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};
 
 
        fpdivr2 #(24) divu0(.clk(clk), .ld(ld), .a(a), .b(b), .q(q), .r(r), .done(done) );
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
endmodule
*/
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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