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

Subversion Repositories ft816float

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /ft816float/trunk/rtl
    from Rev 79 to Rev 80
    Reverse comparison

Rev 79 → Rev 80

/verilog2/BCDAdd8NClk.sv
77,8 → 77,8
 
genvar g,k;
generate begin : gBCDadd
for (g = 0; g < N; g = g + 1) begin
for (k = 0; k < 3; k = k + 1) begin
for (k = 0; k < 3; k = k + 1) begin
for (g = 0; g < N; g = g + 1) begin
initial begin
c[k][g] <= 'b0;
end
/verilog2/BCDMath.sv
100,74 → 100,83
 
endmodule
 
module BCDAddN(ci,a,b,o,co);
parameter N=24;
input ci; // carry input
module BCDAddNClk(clk,ci,a,b,o,co);
parameter N=25;
input clk;
input ci;
input [N*4-1:0] a;
input [N*4-1:0] b;
output [N*4-1:0] o;
output co;
output reg [N*4-1:0] o;
output reg co;
 
reg [N-1:0] cg;
wire [N*4-1:0] s;
reg [N*4-1:0] on [0:3];
reg [3:0] cn;
 
genvar g;
generate begin : gBCDAddN
reg [4:0] hsN [0:N-1];
wire [N:0] c;
 
assign c[0] = ci;
assign co = c[N];
 
for (g = 0; g < N; g = g + 1)
always @*
hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g];
 
for (g = 0; g < N; g = g + 1)
BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]);
generate begin :gAdd
for (g = 0; g < N; g = g + 1)
BCDAddNyb u1 (
.ci(g==0 ? ci : cg[g-1]),
.a(a[g*4+3:g*4]),
.b(b[g*4+3:g*4]),
.o(s[g*4+3:g*4]),
.c(cg[g])
);
end
endgenerate
 
endmodule
always_ff @(posedge clk)
on[0] <= s;
always_ff @(posedge clk)
on[1] <= on[0];
always_ff @(posedge clk)
on[2] <= on[1];
always_ff @(posedge clk)
o <= on[2];
always_ff @(posedge clk)
cn[0] <= cg[N-1];
always_ff @(posedge clk)
cn[1] <= cn[0];
always_ff @(posedge clk)
cn[2] <= cn[1];
always_ff @(posedge clk)
co <= cn[2];
 
module BCDSub(ci,a,b,o,c);
input ci; // carry input
input [7:0] a;
input [7:0] b;
output [7:0] o;
output c;
 
wire c0,c1;
 
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
 
BCDSubAdjust u1 (hdN0,o[3:0],c0);
BCDSubAdjust u2 (hdN1,o[7:4],c);
 
endmodule
 
module BCDSub4(ci,a,b,o,c,c8);
input ci; // carry input
input [15:0] a;
input [15:0] b;
output [15:0] o;
output c;
output c8;
module BCDAddN(ci,a,b,o,co);
parameter N=25;
input ci;
input [N*4-1:0] a;
input [N*4-1:0] b;
output [N*4-1:0] o;
output co;
 
wire c0,c1,c2;
assign c8 = c1;
reg [N-1:0] cg;
wire [N*4-1:0] s;
 
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
wire [4:0] hdN2 = a[11:8] - b[11:8] - c1;
wire [4:0] hdN3 = a[15:12] - b[15:12] - c2;
genvar g;
generate begin :gAdd
for (g = 0; g < N; g = g + 1)
BCDAddNyb u1 (
.ci(g==0 ? ci : cg[g-1]),
.a(a[g*4+3:g*4]),
.b(b[g*4+3:g*4]),
.o(s[g*4+3:g*4]),
.c(cg[g])
);
end
endgenerate
 
BCDSubAdjust u1 (hdN0,o[3:0],c0);
BCDSubAdjust u2 (hdN1,o[7:4],c1);
BCDSubAdjust u3 (hdN2,o[11:8],c2);
BCDSubAdjust u4 (hdN3,o[15:12],c);
assign o = s;
assign co = cg[N-1];
 
endmodule
 
module BCDSubN(ci,a,b,o,co);
/*
module BCDAddN(ci,a,b,o,co);
parameter N=24;
input ci; // carry input
input [N*4-1:0] a;
176,8 → 185,8
output co;
 
genvar g;
generate begin : gBCDSubN
reg [4:0] hdN [0:N-1];
generate begin : gBCDAddN
reg [4:0] hsN [0:N-1];
wire [N:0] c;
 
assign c[0] = ci;
185,16 → 194,15
 
for (g = 0; g < N; g = g + 1)
always @*
hdN[g] = a[g*4+3:g*4] - b[g*4+3:g*4] - c[g];
hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g];
 
for (g = 0; g < N; g = g + 1)
BCDSubAdjust u1 (hdN[g],o[g*4+3:g*4],c[g+1]);
BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]);
end
endgenerate
 
endmodule
 
*/
module BCDAddAdjust(i,o,c);
input [4:0] i;
output [3:0] o;
/verilog2/BCDSubtract.sv
1,10 → 1,49
module BCDSubtract(clk, a, b, o, co);
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BCDSubtract.sv
//
//
// 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 BCDSubtract(clk, a, b, o, sgn);
parameter N=25;
input clk;
input [N*4-1:0] a;
input [N*4-1:0] b;
output reg [N*4-1:0] o;
output reg co;
output reg sgn;
 
wire [(N+1)*4-1:0] bc;
wire [(N+1)*4-1:0] o1, o2, o3;
11,9 → 50,9
wire c;
 
BCDNinesComplementN #(N+1) u1 (.i({4'h0,b}), .o(bc));
BCDAdd8NClk #(.N(N/2+1)) u2 (.clk(clk), .a({8'h00,a}), .b(bc), .o(o1), .ci(1'b0), .co(c));
BCDAddNClk #(.N(N+1)) u2 (.clk(clk), .a({8'h00,a}), .b(bc), .o(o1), .ci(1'b0), .co(c));
BCDNinesComplementN #(N) u3 (.i(o1), .o(o2));
BCDAdd8NClk #(.N(N/2+1)) u4 (.clk(clk), .a(o1), .b({{N*8{1'b0}},1'b1}), .o(o3), .ci(1'b0), .co());
BCDAddNClk #(.N(N+1)) u4 (.clk(clk), .a(o1), .b('d0), .o(o3), .ci(c), .co());
 
always_ff @(posedge clk)
if (c)
21,7 → 60,7
else
o <= o2;
always_ff @(posedge clk)
co <= c;
sgn <= ~c;
 
endmodule
 
/verilog2/DDBinToBCDFract.sv
0,0 → 1,133
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// DDBinToBCD.sv
// Uses the Dubble Dabble algorithm
//
// 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 DDBinToBCDFract(rst, clk, ld, bin, bcd, done);
parameter WID = 128;
parameter DEP = 2; // cascade depth
localparam BCDWID = ((WID+(WID-4)/3)+3) & -4;
input rst;
input clk;
input ld;
input [WID-1:0] bin;
output reg [BCDWID-1:0] bcd;
output reg done;
 
integer k;
genvar n,g;
reg [WID-1:0] binw; // working binary value
reg [WID+3:0] bin10; // working binary value
reg [BCDWID-1:0] bcdwt;
reg [BCDWID-1:0] bcdw [0:DEP-1]; // working bcd value
reg [7:0] bitcnt;
reg [2:0] state;
parameter IDLE = 3'd0;
parameter CHK5 = 3'd1;
parameter SHFT = 3'd2;
parameter DONE = 3'd3;
 
function [BCDWID-1:0] fnRow;
input [BCDWID-1:0] i;
input lsb;
begin
fnRow = 'd0;
for (k = 0; k < BCDWID; k = k + 4)
if (((i >> k) & 4'hF) > 4'd4)
fnRow = fnRow | (((i >> k) & 4'hF) + 4'd3) << k;
else
fnRow = fnRow | ((i >> k) & 4'hf) << k;
fnRow = {fnRow,lsb};
end
endfunction
 
always_comb
bcdw[0] = fnRow(bcdwt,binw[WID-1]);
generate begin : gRows
for (n = 1; n < DEP; n = n + 1)
always_comb
bcdw[n] = fnRow(bcdw[n-1],binw[WID-1-n]);
end
endgenerate
 
always_ff @(posedge clk)
if (WID % DEP) begin
$display("Width must be a multiple of DEP, DEP must be at least 2.");
$finish;
end
 
always_ff @(posedge clk)
if (rst) begin
state <= IDLE;
done <= 1'b1;
bcdwt <= 'd0;
binw <= 'd0;
bitcnt <= BCDWID/4;
end
else begin
if (ld) begin
done <= 1'b0;
bin10 <= bin;
bcdwt <= 'd0;
state <= SHFT;
bcd <= 'd0;
end
else
case(state)
IDLE: ;
SHFT:
begin
bitcnt <= bitcnt - 2'd1;
if (bitcnt==8'd1) begin
state <= DONE;
end
bin10 <= {bin10[WID-1:0],3'b0} + {bin10[WID-1:0],1'b0};
bcdwt <= {bcdwt,bin10[WID+3:WID]};
end
DONE:
begin
bcd <= bcdwt;
done <= 1'b1;
state <= IDLE;
end
default:
state <= IDLE;
endcase
end
 
 
endmodule
/verilog2/DFPAddsub96.sv
63,11 → 63,11
wire [(N+1)*4-1:0] oss10;
wire oss10c;
 
BCDAdd8NClk #(.N((N+2)/2)) ubcdadn1
BCDAddNClk #(.N(N+1)) ubcdadn1
(
.clk(clk),
.a({8'h00,oaa10}),
.b({8'h00,obb10}),
.a({4'h0,oaa10}),
.b({4'h0,obb10}),
.o(oss10),
.ci(1'b0),
.co(oss10c)
76,13 → 76,13
wire [(N+1)*4-1:0] odd10;
wire odd10c;
 
BCDSubtract #(N+2) ubcdsubn1
BCDSubtract #(.N(N+1)) ubcdsubn1
(
.clk(clk),
.a({8'h00,oaa10}),
.b({8'h00,obb10}),
.a({4'h00,oaa10}),
.b({4'h00,obb10}),
.o(odd10),
.co(odd10c)
.sgn(odd10c)
);
/*
BCDSub8NClk #(.N((N+2)/2)) ubcdsdn1
/verilog2/DFPCompare96.sv
41,7 → 41,7
input DFP96 a;
input DFP96 b;
output reg [11:0] o ='d0;
localparam N=34; // number of BCD digits
localparam N=25; // number of BCD digits
 
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
/verilog2/DFPDivide96.sv
134,9 → 134,9
// -----------------------------------------------------------
wire done3a,done3;
// Perform divide
dfdiv #(N+2) u2 (.clk(clk), .ld(ld1), .a({siga,8'b0}), .b({sigb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
wire [7:0] lzcnt_bin = lzcnt[3:0] + (lzcnt[7:4] * 10);
wire [(N+2)*4*2-1:0] divo1 = divo[(N+2)*4*2-1:0] << ({lzcnt_bin,2'b0}+N*4);//WAS FPWID=128?+44
dfdiv2 #(N+2) u2 (.clk(clk), .ld(ld1), .a({siga,8'b0}), .b({sigb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
//wire [7:0] lzcnt_bin = lzcnt[3:0] + (lzcnt[7:4] * 10);
wire [(N+2)*4*2-1:0] divo1 = divo[(N+2)*4*2-1:0] << ({lzcnt-1,2'b0});//WAS FPWID=128?+44
ft_delay #(.WID(1), .DEP(3)) u3 (.clk(clk), .ce(ce), .i(done1), .o(done3a));
assign done3 = done1&done3a;
 
154,7 → 154,7
reg qNaNOut;
 
always @(posedge clk)
if (ce) ex1 <= au.exp - bu.exp + bias - lzcnt_bin;
if (ce) ex1 <= au.exp - bu.exp + bias - (({lzcnt,2'b00} > N+2) ? lzcnt-(N+2) : 0);
 
always @(posedge clk)
if (ce) qNaNOut <= (az&bz)|(aInf&bInf);
/verilog2/dfdiv2.sv
0,0 → 1,234
// ============================================================================
// __
// \\__/ o\ (C) 2006-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// dfdiv2.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 dfdiv2(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 three
localparam 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
 
 
reg [2:0] st;
parameter IDLE = 3'd0;
parameter DDIN1 = 3'd1;
parameter DDIN2 = 3'd2;
parameter CALC = 3'd3;
parameter DDO = 3'd4;
parameter DONE = 3'd5;
parameter DDIN3 = 3'd6;
 
reg rstdd;
reg ldddi,lddiv,ldddo;
reg [1:0] ddidone,ddodone;
wire ddadone,ddbdone,divdone,ddoqdone,ddordone;
wire [N*4-1:0] dda, ddb;
wire [N*4*2-1:0] qdiv;
wire [N*4-1:0] rdiv;
wire [N*4*2-1:0] qo,qo1;
wire [N*4-1:0] ro;
 
DDBCDToBin #(.WID(N*4)) uddi1
(
.rst(rstdd),
.clk(clk),
.ld(ldddi),
.bcd(a),
.bin(dda),
.done(ddadone)
);
 
DDBCDToBin #(.WID(N*4)) uddi2
(
.rst(rstdd),
.clk(clk),
.ld(ldddi),
.bcd(b),
.bin(ddb),
.done(ddbdone)
);
 
fpdivr2 #(.FPWID(N*4)) udiv1
(
.clk_div(clk),
.ld(lddiv),
.a({{N*4{1'b0}},dda}),
.b({{N{1'b0}},ddb}),
.q(qdiv),
.r(rdiv),
.done(divdone),
.lzcnt()
);
 
 
DDBinToBCDFract #(.WID(N*4)) udd3
(
.rst(rstdd),
.clk(clk),
.ld(ldddo),
.bin({qdiv[N*4-1:0],4'h0}),
.bcd(qo1),
.done(ddoqdone)
);
assign qo = {qdiv[N*4+3:N*4],qo1[N*4-1:4]};
 
DDBinToBCDFract #(.WID(N*4)) udd4
(
.rst(rstdd),
.clk(clk),
.ld(ldddo),
.bin(rdiv),
.bcd(ro),
.done(ddordone)
);
 
reg nz;
reg [N-1:0] zc;
genvar g;
generate begin : glzcnt
for (g = N-1; g >= 0; g = g - 1)
always_comb
zc[g] = qo[g*4+3+N*4:g*4+N*4]==0;
end
endgenerate
 
integer n;
always_comb
begin
nz = 1'b0;
lzcnt = 'd0;
for (n = N-1; n >= 0; n = n - 1)
begin
nz = nz | ~zc[n];
if (!nz)
lzcnt = lzcnt + 1;
end
end
 
always_comb
lddiv <= ddidone==2'b11 && st==DDIN3;
always_comb
ldddo <= divdone==1'b1 && st==CALC;
 
always_ff @(posedge clk)
begin
rstdd <= 1'b0;
ldddi <= 1'b0;
case(st)
IDLE: ;
DDIN1:
begin
ldddi <= 1'b1;
st <= DDIN2;
end
DDIN2:
st <= DDIN3;
DDIN3:
begin
if (ddadone) ddidone <= ddidone | {ddbdone,ddadone};
if (ddidone==2'b11)
st <= CALC;
end
CALC:
if (divdone)
st <= DDO;
DDO:
begin
if (ddoqdone) ddodone <= ddodone | {ddordone,ddoqdone};
q <= qo;
r <= ro;
if (ddodone==2'b11)
st <= DONE;
end
DONE:
begin
done <= 1'b1;
end
default:
st <= IDLE;
endcase
if (ld) begin
done <= 1'b0;
rstdd <= 1'b1;
ddidone <= 'd0;
ddodone <= 'd0;
st <= DDIN1;
end
end
 
endmodule
 
module dfdiv2_tb();
 
reg clk;
reg ld;
reg [135:0] a, b;
wire [271:0] q;
wire [135:0] r;
wire [7:0] lzcnt;
 
initial begin
clk = 1'b0;
ld = 1'b0;
a = 136'h99_99999999_00000000_00000000_00000000;
b = 136'h50_00000000_00000000_00000000_00000000;
#20 ld = 1'b1;
#40 ld = 1'b0;
end
 
always #5 clk = ~clk;
 
dfdiv2 #(.N(34)) u1 (
.clk(clk),
.ld(ld),
.a(a),
.b(b),
.q(q),
.r(r),
.done(done),
.lzcnt(lzcnt)
);
endmodule

powered by: WebSVN 2.1.0

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