URL
https://opencores.org/ocsvn/ft816float/ft816float/trunk
Subversion Repositories ft816float
[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpdivr2.v] - Rev 20
Go to most recent revision | Compare with Previous | Blame | View Log
// ============================================================================ // __ // \\__/ o\ (C) 2006-2016 Robert Finch, Stratford // \ __ / All rights reserved. // \/_// robfinch<remove>@finitron.ca // || // // 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/>. // // 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 rx[0] = 0; end always @(posedge clk) if (ld) cnt <= sdval ? 8'b10000000 : WID*2-2; else if (!done) cnt <= cnt - 1; always @(posedge clk) if (ld) begin rxx <= 0; if (sdval) q <= {sdq,{WID{1'b0}}}; 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 // correct remainder assign r = sdval ? sdr : rx[2][DMSB] ? rx[2] + b : rx[2]; assign done = cnt[7]; endmodule /* module fpdivr2_tb(); reg rst; reg clk; reg ld; reg [6:0] cnt; wire ce = 1'b1; wire [23:0] a = 24'h0_4000; 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 fpdivr2 #(24) divu0(.clk(clk), .ld(ld), .a(a), .b(b), .q(q), .r(r), .done(done) ); endmodule */
Go to most recent revision | Compare with Previous | Blame | View Log