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 52 to Rev 53
- ↔ Reverse comparison
Rev 52 → Rev 53
/rtl/verilog2/BCDMath.v
369,6 → 369,78
|
endmodule |
|
module BCDMul4(a,b,o); |
input [15:0] a; |
input [15:0] b; |
output [31:0] o; |
|
wire [15:0] p1,p2,p3,p4; |
wire [31:0] s1; |
|
BCDMul2 u1 (a[7:0],b[7:0],p1); |
BCDMul2 u2 (a[15:8],b[7:0],p2); |
BCDMul2 u3 (a[7:0],b[15:8],p3); |
BCDMul2 u4 (a[15:8],b[15:8],p4); |
|
BCDAddN #(.N(8)) u5 (1'b0,{p4,p1},{8'h0,p2,8'h0},s1); |
BCDAddN #(.N(8)) u6 (1'b0,s1,{8'h0,p3,8'h0},o); |
|
endmodule |
|
module BCDMul8(a,b,o); |
input [31:0] a; |
input [31:0] b; |
output [63:0] o; |
|
wire [31:0] p1,p2,p3,p4; |
wire [63:0] s1; |
|
BCDMul4 u1 (a[15:0],b[15:0],p1); |
BCDMul4 u2 (a[31:16],b[15:0],p2); |
BCDMul4 u3 (a[15:0],b[31:16],p3); |
BCDMul4 u4 (a[31:16],b[31:16],p4); |
|
BCDAddN #(.N(16)) u5 (1'b0,{p4,p1},{16'h0,p2,16'h0},s1); |
BCDAddN #(.N(16)) u6 (1'b0,s1,{16'h0,p3,16'h0},o); |
|
endmodule |
|
module BCDMul16(a,b,o); |
input [63:0] a; |
input [63:0] b; |
output [127:0] o; |
|
wire [63:0] p1,p2,p3,p4; |
wire [127:0] s1; |
|
BCDMul8 u1 (a[31:0],b[31:0],p1); |
BCDMul8 u2 (a[63:32],b[31:0],p2); |
BCDMul8 u3 (a[31:0],b[63:32],p3); |
BCDMul8 u4 (a[63:32],b[63:32],p4); |
|
BCDAddN #(.N(32)) u5 (1'b0,{p4,p1},{32'h0,p2,32'h0},s1); |
BCDAddN #(.N(32)) u6 (1'b0,s1,{32'h0,p3,32'h0},o); |
|
endmodule |
|
module BCDMul32(a,b,o); |
input [127:0] a; |
input [127:0] b; |
output [255:0] o; |
|
wire [127:0] p1,p2,p3,p4; |
wire [255:0] s1; |
|
BCDMul16 u1 (a[63:0],b[63:0],p1); |
BCDMul16 u2 (a[127:64],b[63:0],p2); |
BCDMul16 u3 (a[63:0],b[127:64],p3); |
BCDMul16 u4 (a[127:64],b[127:64],p4); |
|
BCDAddN #(.N(64)) u5 (1'b0,{p4,p1},{64'h0,p2,64'h0},s1); |
BCDAddN #(.N(64)) u6 (1'b0,s1,{64'h0,p3,64'h0},o); |
|
endmodule |
|
module BCDMul_tb(); |
|
wire [15:0] o1,o2,o3,o4; |
/rtl/verilog2/DFPDecompose.sv
40,7 → 40,7
output sgn; |
output sx; |
output [15:0] exp; |
output [95:0] sig; |
output [107:0] sig; |
output xz; |
output vz; |
output inf; |
/rtl/verilog2/DFPMultiply.sv
0,0 → 1,239
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2006-2020 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// DFPMultiply.v |
// - decimal floating point multiplier |
// - can issue every clock cycle |
// - parameterized width |
// |
// |
// 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. |
// |
// |
// Floating Point Multiplier |
// |
// This multiplier handles denormalized numbers. |
// The output format is of an internal expanded representation |
// in preparation to be fed into a normalization unit, then |
// rounding. Basically, it's the same as the regular format |
// except the mantissa is doubled in size, the leading two |
// bits of which are assumed to be whole bits. |
// |
// |
// Floating Point Multiplier |
// |
// Properties: |
// +-inf * +-inf = -+inf (this is handled by exOver) |
// +-inf * 0 = QNaN |
// |
// ============================================================================ |
|
import fp::*; |
|
module DFPMultiply(clk, ce, a, b, o, sign_exe, inf, overflow, underflow); |
input clk; |
input ce; |
input [127:0] a, b; |
output [243:0] o; |
output sign_exe; |
output inf; |
output overflow; |
output underflow; |
parameter DELAY = |
(FPWID == 128 ? 17 : |
FPWID == 80 ? 17 : |
FPWID == 64 ? 13 : |
FPWID == 40 ? 8 : |
FPWID == 32 ? 2 : |
FPWID == 16 ? 2 : 2); |
|
reg [15:0] xo1; // extra bit for sign |
reg [215:0] mo1; |
|
// constants |
wire [15:0] infXp = 16'h9999; // infinite / NaN - all ones |
// The following is the value for an exponent of zero, with the offset |
// eg. 8'h7f for eight bit exponent, 11'h7ff for eleven bit exponent, etc. |
// The following is a template for a quiet nan. (MSB=1) |
wire [107:0] qNaN = {4'h1,{104{1'b0}}}; |
|
// variables |
reg [215:0] sig1; |
wire [15:0] ex2; |
|
// Decompose the operands |
wire sa, sb; // sign bit |
wire [15:0] xa, xb; // exponent bits |
wire sxa, sxb; |
wire [107:0] siga, sigb; |
wire a_dn, b_dn; // a/b is denormalized |
wire aNan, bNan, aNan1, bNan1; |
wire az, bz; |
wire aInf, bInf, aInf1, bInf1; |
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
// Clock #1 |
// - decode the input operands |
// - derive basic information |
// - calculate exponent |
// - calculate fraction |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
// ----------------------------------------------------------- |
// First clock |
// ----------------------------------------------------------- |
|
reg under, over; |
reg [15:0] sum_ex; |
reg sx0; |
|
DFPDecompose u1a (.i(a), .sgn(sa), .sx(sxa), .exp(xa), .sig(siga), .xz(a_dn), .vz(az), .inf(aInf), .nan(aNan) ); |
DFPDecompose u1b (.i(b), .sgn(sb), .sx(sxb), .exp(xb), .sig(sigb), .xz(b_dn), .vz(bz), .inf(bInf), .nan(bNan) ); |
|
// Compute the sum of the exponents. |
// Exponents are sign-magnitude. |
wire [15:0] xapxb, xamxb, xbmxa; |
wire xapxbc, xamxbc, xbmxac; |
BCDAddN #(.N(4)) u1c (.ci(1'b0), .a(xa), .b(xb), .o(xapxb), .co(xapxbc)); |
BCDSubN #(.N(4)) u1d (.ci(1'b0), .a(xa), .b(xb), .o(xamxb), .co(xamxbc)); |
BCDSubN #(.N(4)) u1e (.ci(1'b0), .a(xb), .b(xa), .o(xbmxa), .co(xbmxac)); |
|
always @* |
case({sxa,sxb}) |
2'b11: begin sum_ex <= xapxb; over <= xapxbc; under <= 1'b0; sx0 <= sxa; end |
2'b01: begin sum_ex <= xbmxa; over <= 1'b0; under <= 1'b0; sx0 <= ~xbmxac; end |
2'b10: begin sum_ex <= xamxb; over <= 1'b0; under <= 1'b0; sx0 <= ~xamxbc; end |
2'b00: begin sum_ex <= xapxb; over <= 1'b0; under <= xapxbc; sx0 <= sxa; end |
endcase |
|
wire [255:0] sigoo; |
BCDMul32 u1f (.a({20'h0,siga}),.b({20'h0,sigb}),.o(sigoo)); |
|
always @(posedge clk) |
if (ce) sig1 <= sigoo[215:0]; |
|
// Status |
wire under1, over1; |
|
delay #(.WID(16),.DEP(DELAY)) u3 (.clk(clk), .ce(ce), .i(sum_ex), .o(ex2) ); |
delay #(.WID(1),.DEP(DELAY)) u2a (.clk(clk), .ce(ce), .i(aInf), .o(aInf1) ); |
delay #(.WID(1),.DEP(DELAY)) u2b (.clk(clk), .ce(ce), .i(bInf), .o(bInf1) ); |
delay #(.WID(1),.DEP(DELAY)) u6 (.clk(clk), .ce(ce), .i(under), .o(under1) ); |
delay #(.WID(1),.DEP(DELAY)) u7 (.clk(clk), .ce(ce), .i(over), .o(over1) ); |
|
// determine when a NaN is output |
wire qNaNOut; |
wire [127:0] a1,b1; |
delay #(.WID(1),.DEP(DELAY)) u5 (.clk(clk), .ce(ce), .i((aInf&bz)|(bInf&az)), .o(qNaNOut) ); |
delay #(.WID(1),.DEP(DELAY)) u14 (.clk(clk), .ce(ce), .i(aNan), .o(aNan1) ); |
delay #(.WID(1),.DEP(DELAY)) u15 (.clk(clk), .ce(ce), .i(bNan), .o(bNan1) ); |
delay #(.WID(128),.DEP(DELAY)) u16 (.clk(clk), .ce(ce), .i(a), .o(a1) ); |
delay #(.WID(128),.DEP(DELAY)) u17 (.clk(clk), .ce(ce), .i(b), .o(b1) ); |
|
// ----------------------------------------------------------- |
// Second clock |
// - correct xponent and mantissa for exceptional conditions |
// ----------------------------------------------------------- |
|
wire so1, sx1; |
reg [3:0] st; |
|
delay #(.WID(1),.DEP(1)) u8 (.clk(clk), .ce(ce), .i(~(sa ^ sb)), .o(so1) );// two clock delay! |
delay #(.WID(1),.DEP(1)) u9 (.clk(clk), .ce(ce), .i(sx0), .o(sx1) );// two clock delay! |
|
always @(posedge clk) |
if (ce) |
casez({qNaNOut|aNan1|bNan1,aInf1,bInf1,over1,under1}) |
5'b1????: xo1 = infXp; // qNaN - infinity * zero |
5'b01???: xo1 = infXp; // 'a' infinite |
5'b001??: xo1 = infXp; // 'b' infinite |
5'b0001?: xo1 = infXp; // result overflow |
5'b00001: xo1 = ex2[15:0];//0; // underflow |
default: xo1 = ex2[15:0]; // situation normal |
endcase |
|
// Force mantissa to zero when underflow or zero exponent when not supporting denormals. |
always @(posedge clk) |
if (ce) |
casez({aNan1,bNan1,qNaNOut,aInf1,bInf1,over1|under1}) |
6'b1?????: mo1 = {4'h1,a1[103:0],108'b0}; |
6'b01????: mo1 = {4'h1,b1[103:0],108'b0}; |
6'b001???: mo1 = {4'h1,qNaN|3'd4,108'b0}; // multiply inf * zero |
6'b0001??: mo1 = 0; // mul inf's |
6'b00001?: mo1 = 0; // mul inf's |
6'b000001: mo1 = 0; // mul overflow |
default: mo1 = sig1; |
endcase |
|
always @(posedge clk) |
if (ce) begin |
st[3] <= aNan1|bNan1; |
st[2] <= so1; |
st[1] <= aInf|bInf|over; |
st[0] <= sx1; |
end |
|
delay #(.WID(1),.DEP(DELAY+1)) u10 (.clk(clk), .ce(ce), .i(sa & sb), .o(sign_exe) ); |
delay1 u11 (.clk(clk), .ce(ce), .i(over1), .o(overflow) ); |
delay1 u12 (.clk(clk), .ce(ce), .i(over1), .o(inf) ); |
delay1 u13 (.clk(clk), .ce(ce), .i(under1), .o(underflow) ); |
|
assign o = {st,xo1,mo1,8'h00}; |
|
endmodule |
|
|
// Multiplier with normalization and rounding. |
|
module DFPMultiplynr(clk, ce, a, b, o, rm, sign_exe, inf, overflow, underflow); |
input clk; |
input ce; |
input [127:0] a, b; |
output [127:0] o; |
input [2:0] rm; |
output sign_exe; |
output inf; |
output overflow; |
output underflow; |
|
wire [243:0] o1; |
wire sign_exe1, inf1, overflow1, underflow1; |
wire [131:0] fpn0; |
|
DFPMultiply u1 (clk, ce, a, b, o1, sign_exe1, inf1, overflow1, underflow1); |
DFPNormalize u2(.clk(clk), .ce(ce), .under_i(underflow1), .i(o1), .o(fpn0) ); |
DFPRound u3(.clk(clk), .ce(ce), .rm(rm), .i(fpn0), .o(o) ); |
delay2 #(1) u4(.clk(clk), .ce(ce), .i(sign_exe1), .o(sign_exe)); |
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)); |
endmodule |