URL
https://opencores.org/ocsvn/ft816float/ft816float/trunk
Subversion Repositories ft816float
Compare Revisions
- This comparison shows the changes necessary to convert path
/ft816float/trunk
- from Rev 80 to Rev 81
- ↔ Reverse comparison
Rev 80 → Rev 81
/rtl/verilog2/DFPAddsub96.sv
84,17 → 84,7
.o(odd10), |
.sgn(odd10c) |
); |
/* |
BCDSub8NClk #(.N((N+2)/2)) ubcdsdn1 |
( |
.clk(clk), |
.a({8'h00,oaa10}), |
.b({8'h00,obb10}), |
.o(odd10), |
.ci(1'b0), |
.co(odd10c) |
); |
*/ |
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
// Clock #1 |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
352,7 → 342,7
ft_delay #(.WID(1), .DEP(3+RIP_STAGES)) udly11e (.clk(clk), .ce(ce), .i(op8), .o(op11)); |
ft_delay #(.WID(N*4), .DEP(3+RIP_STAGES)) udly11f (.clk(clk), .ce(ce), .i(siga8), .o(siga11)); |
ft_delay #(.WID(N*4), .DEP(3+RIP_STAGES)) udly11g (.clk(clk), .ce(ce), .i(sigb8), .o(sigb11)); |
ft_delay #(.WID(1), .DEP(1+RIP_STAGES)) udly11h (.clk(clk), .ce(ce), .i(xo10==14'h2FFF), .o(xoinf11)); |
ft_delay #(.WID(1), .DEP(1+RIP_STAGES)) udly11h (.clk(clk), .ce(ce), .i(xo10==12'hBFF), .o(xoinf11)); |
ft_delay #(.WID((N+1)*4+1), .DEP(1+RIP_STAGES)) udly11i (.clk(clk), .ce(ce), .i(realOp10 ? {odd10c,odd10} : {oss10c,oss10}), .o({mab11c,mab11})); |
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
/rtl/verilog2/DFPDivide96.sv
248,7 → 248,7
delay2 #(1) u5(.clk(clk), .ce(ce), .i(inf1), .o(inf)); |
delay2 #(1) u6(.clk(clk), .ce(ce), .i(overflow1), .o(overflow)); |
delay2 #(1) u7(.clk(clk), .ce(ce), .i(underflow1), .o(underflow)); |
ft_delay #(.WID(1),.DEP(11)) u8(.clk(clk), .ce(ce), .i(done1), .o(done1a)); |
ft_delay #(.WID(1),.DEP(14)) u8(.clk(clk), .ce(ce), .i(done1), .o(done1a)); |
assign done = done1&done1a; |
|
endmodule |
/rtl/verilog2/dfdiv.v
1,201 → 1,218
// ============================================================================ |
// __ |
// \\__/ 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 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 as a BCD number |
|
|
reg [1:0] st; |
parameter PREP = 2'd0; |
parameter SUBN = 2'd1; |
parameter DONE = 2'd2; |
|
reg [3:0] cnt; // iteration count |
reg [7:0] dcnt; // digit count |
reg [15:0] clkcnt; |
reg [5:0] digcnt; |
reg [FPWID*2-1:0] qi = 0; |
reg [FPWID+4-1:0] ri = 0; |
reg [FPWID-1:0] bi = 0; |
wire co; |
wire [FPWID+4-1:0] dif; |
reg gotnz; // got a non-zero digit |
(* retiming_forward = 1 *) |
wire [FPWID+4-1:0] dif1; |
(* retiming_forward = 1 *) |
wire co1; |
|
generate begin : gSub |
BCDSub8NClk #(.N((N+2)/2)) ubcds1 |
( |
.clk(clk), |
.a(~N[0] ? {ri,4'h0} : ri), |
.b(~N[0] ? {4'd0,bi,4'h0} : {4'd0,bi}), |
.o(dif), |
.ci(1'b0), |
.co(co) |
); |
end |
endgenerate |
|
always @(posedge clk) |
begin |
case(st) |
SUBN: |
begin |
digcnt <= digcnt - 1'd1; |
if (digcnt=='d0) begin |
clkcnt <= clkcnt + 1'd1; |
digcnt <= 6'd4; |
if (co) begin |
ri <= {ri,qi[FPWID*2-1:FPWID*2-4]}; |
qi <= {qi[FPWID*2-5:0],cnt}; |
cnt <= 4'd0; |
dcnt <= dcnt - 1'd1; |
if (dcnt==6'd0) |
st <= DONE; |
if (dcnt <= FPWID/4) begin |
if (|cnt) |
gotnz <= 1'b1; |
else if (!gotnz) begin |
if (lzcnt[3:0]==4'd9) |
lzcnt <= lzcnt + 4'd7; |
else |
lzcnt <= lzcnt + 1'd1; |
end |
end |
end |
else begin |
if (clkcnt > 600) begin |
ri <= {ri,qi[FPWID*2-1:FPWID*2-4]}; |
qi <= {qi[FPWID*2-5:0],cnt}; |
cnt <= 4'd0; |
dcnt <= dcnt - 1'd1; |
if (dcnt==6'd0) |
st <= DONE; |
if (dcnt <= FPWID/4) begin |
if (|cnt) |
gotnz <= 1'b1; |
else if (!gotnz) begin |
if (lzcnt[3:0]==4'd9) begin |
lzcnt <= lzcnt + 4'd7; |
if (lzcnt[7:4]==4'd9) |
lzcnt[7:4] <= 4'd0; |
end |
else |
lzcnt <= lzcnt + 1'd1; |
end |
end |
end |
else |
begin |
ri <= N[0] ? dif : dif[FPWID+4-1:4]; |
cnt <= cnt + 1'd1; |
end |
end |
end |
end |
DONE: |
begin |
q <= qi; |
r <= ri; |
done <= 1'b1; |
end |
default: |
st <= SUBN; |
endcase |
if (ld) begin |
clkcnt <= 10'd0; |
cnt <= 4'd0; |
digcnt <= 6'd4; |
dcnt <= $ceil((FPWID*2)/4); |
qi <= {a,{FPWID{1'd0}}}; |
ri <= {FPWID{1'd0}}; |
bi <= b; |
st <= SUBN; |
gotnz <= 1'b0; |
lzcnt <= 8'h00; |
done <= 1'b0; |
end |
end |
|
endmodule |
|
module dfdiv_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'h10_00000000_00000000_00000000_00000000; |
b = 136'h20_00000000_00000000_00000000_00000000; |
#20 ld = 1'b1; |
#40 ld = 1'b0; |
end |
|
always #5 clk = ~clk; |
|
dfdiv #(.N(34)) u1 ( |
.clk(clk), |
.ld(ld), |
.a(a), |
.b(b), |
.q(q), |
.r(r), |
.done(done), |
.lzcnt(lzcnt) |
); |
endmodule |
// ============================================================================ |
// __ |
// \\__/ 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 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 as a BCD number |
|
|
reg [1:0] st; |
parameter PREP = 2'd0; |
parameter SUBN = 2'd1; |
parameter DONE = 2'd2; |
|
reg [3:0] cnt; // iteration count |
wire [3:0] cntm1 = cnt;//cnt==4'd0 ? 4'd9 : cnt-1'd1; |
reg [7:0] dcnt; // digit count |
reg [15:0] clkcnt; |
reg [5:0] digcnt; |
reg [FPWID*2-1:0] qi = 0; |
reg [FPWID+4-1:0] ri = 0; |
reg [FPWID-1:0] bi = 0; |
wire sgn; |
wire [FPWID+4-1:0] dif; |
reg gotnz; // got a non-zero digit |
(* retiming_forward = 1 *) |
wire [FPWID+4-1:0] dif1; |
(* retiming_forward = 1 *) |
wire co1; |
|
generate begin : gSub |
BCDSubtract #(.N(N+1)) ubcds1 |
( |
.clk(clk), |
.a(ri), |
.b({4'd0,bi}), |
.o(dif), |
.sgn(sgn) |
); |
end |
endgenerate |
|
/* |
BCDSRL #(.N(N*2)) ushr1 ( |
.ci(1'b0), |
.i(qi), |
.o(q), |
.co() |
); |
*/ |
/* |
BCDSRL #(.N(N)) ushr2 ( |
.ci(1'b0), |
.i(ri), |
.o(r), |
.co() |
); |
*/ |
|
always @(posedge clk) |
begin |
case(st) |
SUBN: |
begin |
digcnt <= digcnt - 1'd1; |
if (digcnt=='d0) begin |
clkcnt <= clkcnt + 1'd1; |
digcnt <= 6'd8; |
if (sgn) begin |
ri <= {ri,qi[FPWID*2-1:FPWID*2-4]}; |
qi <= {qi[FPWID*2-5:0],cntm1}; |
cnt <= 4'd0; |
dcnt <= dcnt - 1'd1; |
if (dcnt=='d0) |
st <= DONE; |
if (dcnt <= FPWID/4) begin |
if (|cnt) |
gotnz <= 1'b1; |
else if (!gotnz) begin |
if (lzcnt[3:0]==4'd9) |
lzcnt <= lzcnt + 4'd7; |
else |
lzcnt <= lzcnt + 1'd1; |
end |
end |
end |
else begin |
if (clkcnt > 600) begin |
ri <= {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; |
if (dcnt <= FPWID/4) begin |
if (|cnt) |
gotnz <= 1'b1; |
else if (!gotnz) begin |
if (lzcnt[3:0]==4'd9) begin |
lzcnt <= lzcnt + 4'd7; |
if (lzcnt[7:4]==4'd9) |
lzcnt[7:4] <= 4'd0; |
end |
else |
lzcnt <= lzcnt + 1'd1; |
end |
end |
end |
else |
begin |
ri <= dif;//N[0] ? dif : dif[FPWID+4-1:4]; |
cnt <= cnt + 1'd1; |
end |
end |
end |
end |
DONE: |
begin |
q <= qi; |
r <= ri; |
done <= 1'b1; |
end |
default: |
st <= SUBN; |
endcase |
if (ld) begin |
clkcnt <= 10'd0; |
cnt <= 4'd0; |
digcnt <= 6'd8; |
dcnt <= $ceil((FPWID*2)/4); |
qi <= {a,{FPWID*2{1'd0}}}; |
ri <= {FPWID{1'd0}}; |
bi <= b; |
st <= SUBN; |
gotnz <= 1'b0; |
lzcnt <= 8'h00; |
done <= 1'b0; |
end |
end |
|
endmodule |
|
module dfdiv_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'h50_00000000_00000000_00000000_00000000; |
b = 136'h50_00000000_00000000_00000000_00000000; |
#20 ld = 1'b1; |
#40 ld = 1'b0; |
end |
|
always #5 clk = ~clk; |
|
dfdiv #(.N(34)) u1 ( |
.clk(clk), |
.ld(ld), |
.a(a), |
.b(b), |
.q(q), |
.r(r), |
.done(done), |
.lzcnt(lzcnt) |
); |
endmodule |
/rtl/verilog2/dfmul.sv
1,148 → 1,148
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2006-2022 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// dfmul.v |
// Decimal Float multiplier 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 dfmul(clk, ld, a, b, p, done); |
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] p; |
output reg done; |
|
|
reg [1:0] st; |
parameter PREP = 2'd0; |
parameter ADDN = 2'd1; |
parameter DONE = 2'd2; |
|
reg [7:0] dcnt; // digit count |
reg [9:0] clkcnt; |
reg [FPWID*2-1:0] pi = 0; |
reg [FPWID-1:0] ai = 0; |
reg [FPWID*2-1:0] bi = 0; |
wire [FPWID*2-1:0] sum; |
reg [5:0] digcnt; |
|
BCDAdd8NClk #(.N(FPWID/4)) ubcdm1 |
( |
.clk(clk), |
.a(pi), |
.b(bi), |
.o(sum), |
.ci(1'b0), |
.co() |
); |
|
always_ff @(posedge clk) |
begin |
case(st) |
ADDN: |
begin |
clkcnt <= clkcnt + 1'd1; |
if (ai[FPWID-1:FPWID-4]!=4'h0) begin |
if (digcnt=='d0) begin |
pi <= sum; |
digcnt <= 6'd3; |
ai[FPWID-1:FPWID-4] <= ai[FPWID-1:FPWID-4] - 1'd1; |
end |
else |
digcnt <= digcnt - 1'd1; |
end |
else begin |
ai <= {ai,4'h0}; |
bi <= {4'h0,bi[FPWID*2-1:4]}; |
pi <= pi; |
dcnt <= dcnt - 1'd1; |
if (dcnt=='d0) |
st <= DONE; |
end |
end |
DONE: |
begin |
p <= pi; |
done <= 1'b1; |
end |
default: |
st <= ADDN; |
endcase |
if (ld) begin |
clkcnt <= 10'd0; |
digcnt <= 6'd3; |
dcnt <= (FPWID*2)/4; |
pi <= {FPWID*2{1'b0}}; |
ai <= a; |
bi <= {4'h0,b,{FPWID-4{1'b0}}}; |
st <= ADDN; |
done <= 1'b0; |
end |
end |
|
endmodule |
|
module dfmul_tb(); |
|
reg clk; |
reg ld; |
reg [107:0] a, b; |
wire [215:0] p; |
|
initial begin |
clk = 1'b0; |
ld = 1'b0; |
a = 108'h099_00000000_00000000_00000000; |
b = 108'h560_00000000_00000000_00000000; |
#20 ld = 1'b1; |
#40 ld = 1'b0; |
end |
|
always #5 clk = ~clk; |
|
dfmul #(27) u1 ( |
.clk(clk), |
.ld(ld), |
.a(a), |
.b(b), |
.p(p), |
.done(done) |
); |
endmodule |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2006-2022 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// dfmul.v |
// Decimal Float multiplier 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 dfmul(clk, ld, a, b, p, done); |
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] p; |
output reg done; |
|
|
reg [1:0] st; |
parameter PREP = 2'd0; |
parameter ADDN = 2'd1; |
parameter DONE = 2'd2; |
|
reg [7:0] dcnt; // digit count |
reg [9:0] clkcnt; |
reg [FPWID*2-1:0] pi = 0; |
reg [FPWID-1:0] ai = 0; |
reg [FPWID*2-1:0] bi = 0; |
wire [FPWID*2-1:0] sum; |
reg [5:0] digcnt; |
|
BCDAddNClk #(.N(FPWID/2)) ubcdm1 |
( |
.clk(clk), |
.a(pi), |
.b(bi), |
.o(sum), |
.ci(1'b0), |
.co() |
); |
|
always_ff @(posedge clk) |
begin |
case(st) |
ADDN: |
begin |
clkcnt <= clkcnt + 1'd1; |
if (ai[FPWID-1:FPWID-4]!=4'h0) begin |
if (digcnt=='d0) begin |
pi <= sum; |
digcnt <= 6'd4; |
ai[FPWID-1:FPWID-4] <= ai[FPWID-1:FPWID-4] - 1'd1; |
end |
else |
digcnt <= digcnt - 1'd1; |
end |
else begin |
ai <= {ai,4'h0}; |
bi <= {4'h0,bi[FPWID*2-1:4]}; |
pi <= pi; |
dcnt <= dcnt - 1'd1; |
if (dcnt=='d0) |
st <= DONE; |
end |
end |
DONE: |
begin |
p <= pi; |
done <= 1'b1; |
end |
default: |
st <= ADDN; |
endcase |
if (ld) begin |
clkcnt <= 10'd0; |
digcnt <= 6'd4; |
dcnt <= (FPWID*2)/4; |
pi <= {FPWID*2{1'b0}}; |
ai <= a; |
bi <= {4'h0,b,{FPWID-4{1'b0}}}; |
st <= ADDN; |
done <= 1'b0; |
end |
end |
|
endmodule |
|
module dfmul_tb(); |
|
reg clk; |
reg ld; |
reg [107:0] a, b; |
wire [215:0] p; |
|
initial begin |
clk = 1'b0; |
ld = 1'b0; |
a = 108'h099_00000000_00000000_00000000; |
b = 108'h560_00000000_00000000_00000000; |
#20 ld = 1'b1; |
#40 ld = 1'b0; |
end |
|
always #5 clk = ~clk; |
|
dfmul #(27) u1 ( |
.clk(clk), |
.ld(ld), |
.a(a), |
.b(b), |
.p(p), |
.done(done) |
); |
endmodule |