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

Subversion Repositories double_fpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /double_fpu/branches/avendor/pipeline
    from Rev 8 to Rev 13
    Reverse comparison

Rev 8 → Rev 13

/Readme_pipeline.txt
0,0 → 1,114
The verilog files, fpu_addsub.v and fpu_mul.v, are pipelined versions of
floating point operators. The four rounding modes (Nearest, To Zero, To
Positive Infintiy, To Negative Infinity) are supported by these operators.
Denormalized numbers are not supported, but instead are treated as 0.
If infinity or NaN is on either of the inputs,
then infinity will be the output. Addition and subtraction have a latency
of 24 clock cycles, and then an output is available on each clock cycle after the latency.
Multiplication has a latency of 21 clock cycles, and
then an output is available on each clock cycle after the latency.
 
For addition and subtraction, fpu_addsub.v was synthesized with an estimated
frequency of 259 MHz for a Virtex5 device. The synthesis results are below.
The file, fpu_addsub_TB.v, is the testbench used to simulate fpu_addsub.v.
 
For multiplication, fpu_mul.v was synthesized with an estimated
frequency of 393 MHz for a Virtex5 device. The synthesis results are below.
The file, fpu_mul_TB.v, is the testbench used to simulate fpu_mul.v.
 
Please email me any questions.
 
David Lundgren
davidklun@gmail.com
 
addsub synthesis results:
 
---------------------------------------
Resource Usage Report for fpu_addsub
 
Mapping to part: xc5vsx95tff1136-2
Cell usage:
FDE 55 uses
FDR 6 uses
FDRE 2848 uses
GND 1 use
MUXCY 8 uses
MUXCY_L 293 uses
VCC 1 use
XORCY 240 uses
XORCY_L 5 uses
LUT1 98 uses
LUT2 377 uses
LUT3 522 uses
LUT4 151 uses
LUT5 101 uses
LUT6 517 uses
 
I/O ports: 199
I/O primitives: 198
IBUF 133 uses
OBUF 65 uses
 
BUFGP 1 use
 
SRL primitives:
SRLC32E 1 use
SRL16E 54 uses
 
I/O Register bits: 0
Register bits not including I/Os: 2909 (4%)
 
Global Clock Buffers: 1 of 32 (3%)
 
Total load per clock:
fpu_addsub|clk: 2964
 
Mapping Summary:
Total LUTs: 1821 (3%)
 
------------------------------
 
multiply synthesis results:
 
---------------------------------------
Resource Usage Report for fpu_mul
 
Mapping to part: xc5vsx95tff1136-2
Cell usage:
DSP48E 9 uses
FDE 83 uses
FDRE 1536 uses
FDRSE 11 uses
GND 1 use
MUXCY 7 uses
MUXCY_L 164 uses
VCC 1 use
XORCY 128 uses
XORCY_L 5 uses
LUT1 82 uses
LUT2 215 uses
LUT3 170 uses
LUT4 48 uses
LUT5 13 uses
LUT6 32 uses
 
I/O ports: 198
I/O primitives: 197
IBUF 132 uses
OBUF 65 uses
 
BUFGP 1 use
 
SRL primitives:
SRL16E 83 uses
 
I/O Register bits: 0
Register bits not including I/Os: 1630 (2%)
 
Global Clock Buffers: 1 of 32 (3%)
 
Total load per clock:
fpu_mul|clk: 1722
 
Mapping Summary:
Total LUTs: 643 (1%)
/fpu_addsub.v
0,0 → 1,367
/////////////////////////////////////////////////////////////////////
//// ////
//// FPU ////
//// Floating Point Unit (Double precision) ////
//// ////
//// Author: David Lundgren ////
//// davidklun@gmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 David Lundgren ////
//// davidklun@gmail.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// fpu_op, add = 0, subtract = 1
// rmode = 00 (nearest), 01 (to zero), 10 (+ infinity), 11 (- infinity)
 
`timescale 1ns / 100ps
 
module fpu_addsub( clk, rst, enable, fpu_op, rmode, opa, opb, out, ready);
input clk;
input rst;
input enable;
input fpu_op;
input [1:0] rmode;
input [63:0] opa, opb;
output [63:0] out;
output ready;
 
 
 
reg [63:0] outfp, out;
reg [1:0] rm_1, rm_2, rm_3, rm_4, rm_5, rm_6, rm_7, rm_8, rm_9;
reg [1:0] rm_10, rm_11, rm_12, rm_13, rm_14, rm_15, rm_16;
reg sign, sign_a, sign_b, fpu_op_1, fpu_op_2, fpu_op_3, fpu_op_final;
reg fpuf_2, fpuf_3, fpuf_4, fpuf_5, fpuf_6, fpuf_7, fpuf_8, fpuf_9, fpuf_10;
reg fpuf_11, fpuf_12, fpuf_13, fpuf_14, fpuf_15, fpuf_16;
reg fpuf_17, fpuf_18, fpuf_19, fpuf_20, fpuf_21;
reg sign_a2, sign_a3, sign_b2, sign_b3, sign_2, sign_3, sign_4, sign_5, sign_6;
reg sign_7, sign_8, sign_9, sign_10, sign_11, sign_12;
reg sign_13, sign_14, sign_15, sign_16, sign_17, sign_18, sign_19;
reg [10:0] exponent_a, exponent_b, expa_2, expb_2, expa_3, expb_3;
reg [51:0] mantissa_a, mantissa_b, mana_2, mana_3, manb_2, manb_3;
reg expa_et_inf, expb_et_inf, input_is_inf, in_inf2, in_inf3, in_inf4, in_inf5;
reg in_inf6, in_inf7, in_inf8, in_inf9, in_inf10, in_inf11, in_inf12, in_inf13;
reg in_inf14, in_inf15, in_inf16, in_inf17, in_inf18, in_inf19, in_inf20;
reg in_inf21, expa_gt_expb, expa_et_expb, mana_gtet_manb, a_gtet_b;
reg [10:0] exponent_small, exponent_large, expl_2, expl_3, expl_4;
reg [10:0] expl_5, expl_6, expl_7, expl_8, expl_9, expl_10, expl_11;
reg [51:0] mantissa_small, mantissa_large;
reg [51:0] mantissa_small_2, mantissa_large_2;
reg [51:0] mantissa_small_3, mantissa_large_3;
reg exp_small_et0, exp_large_et0, exp_small_et0_2, exp_large_et0_2;
reg [10:0] exponent_diff, exponent_diff_2, exponent_diff_3;
reg [107:0] bits_shifted_out, bits_shifted_out_2;
reg bits_shifted;
reg [55:0] large_add, large_add_2, large_add_3, small_add;
reg [55:0] small_shift, small_shift_2, small_shift_3, small_shift_4;
reg [55:0] large_add_4, large_add_5;
reg small_shift_nonzero;
reg small_is_nonzero, small_is_nonzero_2, small_is_nonzero_3;
reg small_fraction_enable;
wire [55:0] small_shift_LSB = { 55'b0, 1'b1 };
reg [55:0] sum, sum_2, sum_3, sum_4, sum_5;
reg [55:0] sum_6, sum_7, sum_8, sum_9, sum_10, sum_11;
reg sum_overflow, sumround_overflow, sum_lsb, sum_lsb_2;
reg [10:0] exponent_add, exp_add_2, exponent_sub, exp_sub_2;
reg [10:0] exp_sub_3, exp_sub_4, exp_sub_5, exp_sub_6, exp_sub_7;
reg [10:0] exp_sub_8, exp_add_3, exp_add_4, exp_add_5, exp_add_6;
reg [10:0] exp_add_7, exp_add_8, exp_add_9;
reg [5:0] diff_shift, diff_shift_2;
reg [55:0] diff, diff_2, diff_3, diff_4, diff_5;
reg [55:0] diff_6, diff_7, diff_8, diff_9, diff_10, diff_11;
reg diffshift_gt_exponent, diffshift_et_55, diffround_overflow;
reg round_nearest_mode, round_posinf_mode, round_neginf_mode;
reg round_nearest_trigger, round_nearest_exception;
reg round_nearest_enable, round_posinf_trigger, round_posinf_enable;
reg round_neginf_trigger, round_neginf_enable, round_enable;
reg ready, count_ready, count_ready_0;
reg [4:0] count;
 
always @(posedge clk)
begin
if (rst) begin
fpu_op_1 <= 0; fpu_op_final <= 0; fpu_op_2 <= 0;
fpu_op_3 <= 0; fpuf_2 <= 0; fpuf_3 <= 0; fpuf_4 <= 0;
fpuf_5 <= 0; fpuf_6 <= 0; fpuf_7 <= 0; fpuf_8 <= 0; fpuf_9 <= 0;
fpuf_10 <= 0; fpuf_11 <= 0; fpuf_12 <= 0; fpuf_13 <= 0; fpuf_14 <= 0;
fpuf_15 <= 0; fpuf_16 <= 0; fpuf_17 <= 0; fpuf_18 <= 0; fpuf_19 <= 0;
fpuf_20 <= 0; fpuf_21 <= 0;
rm_1 <= 0; rm_2 <= 0; rm_3 <= 0; rm_4 <= 0; rm_5 <= 0;
rm_6 <= 0; rm_7 <= 0; rm_8 <= 0; rm_9 <= 0; rm_10 <= 0; rm_11 <= 0;
rm_12 <= 0; rm_13 <= 0; rm_14 <= 0; rm_15 <= 0; rm_16 <= 0; sign_a <= 0;
sign_b <= 0; sign_a2 <= 0; sign_b2 <= 0; sign_a3 <= 0; sign_b3 <= 0;
exponent_a <= 0; exponent_b <= 0; expa_2 <= 0; expa_3 <= 0;
expb_2 <= 0; expb_3 <= 0; mantissa_a <= 0; mantissa_b <= 0; mana_2 <= 0; mana_3 <= 0;
manb_2 <= 0; manb_3 <= 0; expa_et_inf <= 0; expb_et_inf <= 0;
input_is_inf <= 0; in_inf2 <= 0; in_inf3 <= 0; in_inf4 <= 0; in_inf5 <= 0;
in_inf6 <= 0; in_inf7 <= 0; in_inf8 <= 0; in_inf9 <= 0; in_inf10 <= 0;
in_inf11 <= 0; in_inf12 <= 0; in_inf13 <= 0; in_inf14 <= 0; in_inf15 <= 0;
in_inf16 <= 0; in_inf17 <= 0; in_inf18 <= 0; in_inf19 <= 0; in_inf20 <= 0;
in_inf21 <= 0; expa_gt_expb <= 0; expa_et_expb <= 0; mana_gtet_manb <= 0;
a_gtet_b <= 0; sign <= 0; sign_2 <= 0; sign_3 <= 0; sign_4 <= 0; sign_5 <= 0;
sign_6 <= 0; sign_7 <= 0; sign_8 <= 0; sign_9 <= 0;
sign_10 <= 0; sign_11 <= 0; sign_12 <= 0; sign_13 <= 0; sign_14 <= 0;
sign_15 <= 0; sign_16 <= 0; sign_17 <= 0; sign_18 <= 0; sign_19 <= 0;
exponent_small <= 0; exponent_large <= 0; expl_2 <= 0;
expl_3 <= 0; expl_4 <= 0; expl_5 <= 0; expl_6 <= 0; expl_7 <= 0;
expl_8 <= 0; expl_9 <= 0; expl_10 <= 0; expl_11 <= 0;
exp_small_et0 <= 0; exp_large_et0 <= 0;
exp_small_et0_2 <= 0; exp_large_et0_2 <= 0;
mantissa_small <= 0; mantissa_large <= 0;
mantissa_small_2 <= 0; mantissa_large_2 <= 0;
mantissa_small_3 <= 0; mantissa_large_3 <= 0;
exponent_diff <= 0; exponent_diff_2 <= 0; exponent_diff_3 <= 0;
bits_shifted_out <= 0;
bits_shifted_out_2 <= 0; bits_shifted <= 0;
large_add <= 0; large_add_2 <= 0;
large_add_3 <= 0; large_add_4 <= 0; large_add_5 <= 0; small_add <= 0;
small_shift <= 0; small_shift_2 <= 0; small_shift_3 <= 0;
small_shift_4 <= 0; small_shift_nonzero <= 0;
small_is_nonzero <= 0; small_is_nonzero_2 <= 0; small_is_nonzero_3 <= 0;
small_fraction_enable <= 0;
sum <= 0; sum_2 <= 0; sum_overflow <= 0; sum_3 <= 0; sum_4 <= 0;
sum_5 <= 0; sum_6 <= 0; sum_7 <= 0; sum_8 <= 0; sum_9 <= 0; sum_10 <= 0;
sum_11 <= 0; sumround_overflow <= 0; sum_lsb <= 0; sum_lsb_2 <= 0;
exponent_add <= 0; exp_add_2 <= 0; exp_add_3 <= 0; exp_add_4 <= 0;
exp_add_5 <= 0; exp_add_6 <= 0; exp_add_7 <= 0; exp_add_8 <= 0;
exp_add_9 <= 0; diff_shift_2 <= 0; diff <= 0;
diffshift_gt_exponent <= 0; diffshift_et_55 <= 0; diff_2 <= 0;
diff_3 <= 0; diff_4 <= 0; diff_5 <= 0; diff_6 <= 0; diff_7 <= 0; diff_8 <= 0;
diff_9 <= 0; diff_10 <= 0;
diff_11 <= 0; diffround_overflow <= 0; exponent_sub <= 0;
exp_sub_2 <= 0; exp_sub_3 <= 0; exp_sub_4 <= 0; exp_sub_5 <= 0;
exp_sub_6 <= 0; exp_sub_7 <= 0; exp_sub_8 <= 0; outfp <= 0;
round_nearest_mode <= 0; round_posinf_mode <= 0; round_neginf_mode <= 0; round_nearest_trigger <= 0;
round_nearest_exception <= 0; round_nearest_enable <= 0; round_posinf_trigger <= 0; round_posinf_enable <= 0;
round_neginf_trigger <= 0; round_neginf_enable <= 0; round_enable <= 0;
end
else if (enable) begin
fpu_op_1 <= fpu_op; fpu_op_final <= fpu_op_1 ^ (sign_a ^ sign_b);
fpuf_2 <= fpu_op_final; fpuf_3 <= fpuf_2; fpuf_4 <= fpuf_3;
fpuf_5 <= fpuf_4; fpuf_6 <= fpuf_5; fpuf_7 <= fpuf_6; fpuf_8 <= fpuf_7;
fpuf_9 <= fpuf_8; fpuf_10 <= fpuf_9; fpuf_11 <= fpuf_10; fpuf_12 <= fpuf_11;
fpuf_13 <= fpuf_12; fpuf_14 <= fpuf_13; fpuf_15 <= fpuf_14;
fpuf_16 <= fpuf_15; fpuf_17 <= fpuf_16; fpuf_18 <= fpuf_17;
fpuf_19 <= fpuf_18; fpuf_20 <= fpuf_19; fpuf_21 <= fpuf_20;
fpu_op_2 <= fpu_op_1; fpu_op_3 <= fpu_op_2;
rm_1 <= rmode; rm_2 <= rm_1; rm_3 <= rm_2; rm_4 <= rm_3;
rm_5 <= rm_4; rm_6 <= rm_5; rm_7 <= rm_6; rm_8 <= rm_7; rm_9 <= rm_8;
rm_10 <= rm_9; rm_11 <= rm_10; rm_12 <= rm_11; rm_13 <= rm_12;
rm_14 <= rm_13; rm_15 <= rm_14; rm_16 <= rm_15;
sign_a <= opa[63]; sign_b <= opb[63]; sign_a2 <= sign_a;
sign_b2 <= sign_b; sign_a3 <= sign_a2; sign_b3 <= sign_b2;
exponent_a <= opa[62:52]; expa_2 <= exponent_a; expa_3 <= expa_2;
exponent_b <= opb[62:52]; expb_2 <= exponent_b; expb_3 <= expb_2;
mantissa_a <= opa[51:0]; mana_2 <= mantissa_a; mana_3 <= mana_2;
mantissa_b <= opb[51:0]; manb_2 <= mantissa_b; manb_3 <= manb_2;
expa_et_inf <= exponent_a == 2047;
expb_et_inf <= exponent_b == 2047;
input_is_inf <= expa_et_inf | expb_et_inf; in_inf2 <= input_is_inf;
in_inf3 <= in_inf2; in_inf4 <= in_inf3; in_inf5 <= in_inf4; in_inf6 <= in_inf5;
in_inf7 <= in_inf6; in_inf8 <= in_inf7; in_inf9 <= in_inf8; in_inf10 <= in_inf9;
in_inf11 <= in_inf10; in_inf12 <= in_inf11; in_inf13 <= in_inf12;
in_inf14 <= in_inf13; in_inf15 <= in_inf14; in_inf16 <= in_inf15;
in_inf17 <= in_inf16; in_inf18 <= in_inf17; in_inf19 <= in_inf18;
in_inf20 <= in_inf19; in_inf21 <= in_inf20;
expa_gt_expb <= exponent_a > exponent_b;
expa_et_expb <= exponent_a == exponent_b;
mana_gtet_manb <= mantissa_a >= mantissa_b;
a_gtet_b <= expa_gt_expb | (expa_et_expb & mana_gtet_manb);
sign <= a_gtet_b ? sign_a3 :!sign_b3 ^ (fpu_op_3 == 0);
sign_2 <= sign; sign_3 <= sign_2; sign_4 <= sign_3; sign_5 <= sign_4;
sign_6 <= sign_5; sign_7 <= sign_6; sign_8 <= sign_7; sign_9 <= sign_8;
sign_10 <= sign_9; sign_11 <= sign_10; sign_12 <= sign_11;
sign_13 <= sign_12; sign_14 <= sign_13; sign_15 <= sign_14;
sign_16 <= sign_15; sign_17 <= sign_16; sign_18 <= sign_17;
sign_19 <= sign_18;
exponent_small <= a_gtet_b ? expb_3 : expa_3;
exponent_large <= a_gtet_b ? expa_3 : expb_3;
expl_2 <= exponent_large; expl_3 <= expl_2; expl_4 <= expl_3;
expl_5 <= expl_4; expl_6 <= expl_5; expl_7 <= expl_6; expl_8 <= expl_7;
expl_9 <= expl_8; expl_10 <= expl_9; expl_11 <= expl_10;
exp_small_et0 <= exponent_small == 0;
exp_large_et0 <= exponent_large == 0;
exp_small_et0_2 <= exp_small_et0;
exp_large_et0_2 <= exp_large_et0;
mantissa_small <= a_gtet_b ? manb_3 : mana_3;
mantissa_large <= a_gtet_b ? mana_3 : manb_3;
mantissa_small_2 <= mantissa_small;
mantissa_large_2 <= mantissa_large;
mantissa_small_3 <= exp_small_et0 ? 0 : mantissa_small_2;
mantissa_large_3 <= exp_large_et0 ? 0 : mantissa_large_2;
exponent_diff <= exponent_large - exponent_small;
exponent_diff_2 <= exponent_diff;
exponent_diff_3 <= exponent_diff_2;
bits_shifted_out <= exp_small_et0 ? 108'b0 : { 1'b1, mantissa_small_2, 55'b0 };
bits_shifted_out_2 <= bits_shifted_out >> exponent_diff_2;
bits_shifted <= |bits_shifted_out_2[52:0];
large_add <= { 1'b0, !exp_large_et0_2, mantissa_large_3, 2'b0};
large_add_2 <= large_add; large_add_3 <= large_add_2;
large_add_4 <= large_add_3; large_add_5 <= large_add_4;
small_add <= { 1'b0, !exp_small_et0_2, mantissa_small_3, 2'b0};
small_shift <= small_add >> exponent_diff_3;
small_shift_2 <= { small_shift[55:1], (bits_shifted | small_shift[0]) };
small_shift_3 <= small_shift_2;
small_fraction_enable <= small_is_nonzero_3 & !small_shift_nonzero;
small_shift_4 <= small_fraction_enable ? small_shift_LSB : small_shift_3;
small_shift_nonzero <= |small_shift[54:0];
small_is_nonzero <= !exp_small_et0_2;
small_is_nonzero_2 <= small_is_nonzero; small_is_nonzero_3 <= small_is_nonzero_2;
sum <= large_add_5 + small_shift_4;
sum_overflow <= sum[55];
sum_2 <= sum; sum_lsb <= sum[0];
sum_3 <= sum_overflow ? sum_2 >> 1 : sum_2; sum_lsb_2 <= sum_lsb;
sum_4 <= { sum_3[55:1], sum_lsb_2 | sum_3[0] };
sum_5 <= sum_4; sum_6 <= sum_5; sum_7 <= sum_6; sum_8 <= sum_7;
exponent_add <= sum_overflow ? expl_10 + 1: expl_10;
exp_add_2 <= exponent_add;
diff_shift_2 <= diff_shift;
diff <= large_add_5 - small_shift_4; diff_2 <= diff; diff_3 <= diff_2;
diffshift_gt_exponent <= diff_shift > expl_10;
diffshift_et_55 <= diff_shift_2 == 55;
diff_4 <= diffshift_gt_exponent ? diff_3 << expl_11 : diff_3 << diff_shift_2;
diff_5 <= diff_4; diff_6 <= diff_5; diff_7 <= diff_6; diff_8 <= diff_7;
exponent_sub <= diffshift_gt_exponent ? 0 : (expl_11 - diff_shift_2);
exp_sub_2 <= diffshift_et_55 ? 0 : exponent_sub;
round_nearest_mode <= rm_16 == 2'b00;
round_posinf_mode <= rm_16 == 2'b10;
round_neginf_mode <= rm_16 == 2'b11;
round_nearest_trigger <= fpuf_15 ? diff_5[1] : sum_5[1];
round_nearest_exception <= fpuf_15 ? !diff_5[0] & !diff_5[2] : !sum_5[0] & !sum_5[2];
round_nearest_enable <= round_nearest_mode & round_nearest_trigger & !round_nearest_exception;
round_posinf_trigger <= fpuf_15 ? |diff_5[1:0] & !sign_13 : |sum_5[1:0] & !sign_13;
round_posinf_enable <= round_posinf_mode & round_posinf_trigger;
round_neginf_trigger <= fpuf_15 ? |diff_5[1:0] & sign_13 : |sum_5[1:0] & sign_13;
round_neginf_enable <= round_neginf_mode & round_neginf_trigger;
round_enable <= round_posinf_enable | round_neginf_enable | round_nearest_enable;
sum_9 <= round_enable ? sum_8 + 4 : sum_8;
sumround_overflow <= sum_9[55]; sum_10 <= sum_9;
sum_11 <= sumround_overflow ? sum_10 >> 1 : sum_10;
diff_9 <= round_enable ? diff_8 + 4 : diff_8;
diffround_overflow <= diff_9[55]; diff_10 <= diff_9;
diff_11 <= diffround_overflow ? diff_10 >> 1 : diff_10;
exp_add_3 <= exp_add_2; exp_add_4 <= exp_add_3; exp_add_5 <= exp_add_4;
exp_add_6 <= exp_add_5; exp_add_7 <= exp_add_6; exp_add_8 <= exp_add_7;
exp_add_9 <= sumround_overflow ? exp_add_8 + 1 : exp_add_8;
exp_sub_3 <= exp_sub_2; exp_sub_4 <= exp_sub_3; exp_sub_5 <= exp_sub_4;
exp_sub_6 <= exp_sub_5; exp_sub_7 <= exp_sub_6;
exp_sub_8 <= diffround_overflow ? exp_sub_7 + 1 : exp_sub_7;
outfp <= fpuf_21 ? {sign_19, exp_sub_8, diff_11[53:2]} : {sign_19, exp_add_9, sum_11[53:2]};
end
end
 
 
always @(posedge clk)
casex(diff[54:0])
55'b1??????????????????????????????????????????????????????: diff_shift <= 0;
55'b01?????????????????????????????????????????????????????: diff_shift <= 1;
55'b001????????????????????????????????????????????????????: diff_shift <= 2;
55'b0001???????????????????????????????????????????????????: diff_shift <= 3;
55'b00001??????????????????????????????????????????????????: diff_shift <= 4;
55'b000001?????????????????????????????????????????????????: diff_shift <= 5;
55'b0000001????????????????????????????????????????????????: diff_shift <= 6;
55'b00000001???????????????????????????????????????????????: diff_shift <= 7;
55'b000000001??????????????????????????????????????????????: diff_shift <= 8;
55'b0000000001?????????????????????????????????????????????: diff_shift <= 9;
55'b00000000001????????????????????????????????????????????: diff_shift <= 10;
55'b000000000001???????????????????????????????????????????: diff_shift <= 11;
55'b0000000000001??????????????????????????????????????????: diff_shift <= 12;
55'b00000000000001?????????????????????????????????????????: diff_shift <= 13;
55'b000000000000001????????????????????????????????????????: diff_shift <= 14;
55'b0000000000000001???????????????????????????????????????: diff_shift <= 15;
55'b00000000000000001??????????????????????????????????????: diff_shift <= 16;
55'b000000000000000001?????????????????????????????????????: diff_shift <= 17;
55'b0000000000000000001????????????????????????????????????: diff_shift <= 18;
55'b00000000000000000001???????????????????????????????????: diff_shift <= 19;
55'b000000000000000000001??????????????????????????????????: diff_shift <= 20;
55'b0000000000000000000001?????????????????????????????????: diff_shift <= 21;
55'b00000000000000000000001????????????????????????????????: diff_shift <= 22;
55'b000000000000000000000001???????????????????????????????: diff_shift <= 23;
55'b0000000000000000000000001??????????????????????????????: diff_shift <= 24;
55'b00000000000000000000000001?????????????????????????????: diff_shift <= 25;
55'b000000000000000000000000001????????????????????????????: diff_shift <= 26;
55'b0000000000000000000000000001???????????????????????????: diff_shift <= 27;
55'b00000000000000000000000000001??????????????????????????: diff_shift <= 28;
55'b000000000000000000000000000001?????????????????????????: diff_shift <= 29;
55'b0000000000000000000000000000001????????????????????????: diff_shift <= 30;
55'b00000000000000000000000000000001???????????????????????: diff_shift <= 31;
55'b000000000000000000000000000000001??????????????????????: diff_shift <= 32;
55'b0000000000000000000000000000000001?????????????????????: diff_shift <= 33;
55'b00000000000000000000000000000000001????????????????????: diff_shift <= 34;
55'b000000000000000000000000000000000001???????????????????: diff_shift <= 35;
55'b0000000000000000000000000000000000001??????????????????: diff_shift <= 36;
55'b00000000000000000000000000000000000001?????????????????: diff_shift <= 37;
55'b000000000000000000000000000000000000001????????????????: diff_shift <= 38;
55'b0000000000000000000000000000000000000001???????????????: diff_shift <= 39;
55'b00000000000000000000000000000000000000001??????????????: diff_shift <= 40;
55'b000000000000000000000000000000000000000001?????????????: diff_shift <= 41;
55'b0000000000000000000000000000000000000000001????????????: diff_shift <= 42;
55'b00000000000000000000000000000000000000000001???????????: diff_shift <= 43;
55'b000000000000000000000000000000000000000000001??????????: diff_shift <= 44;
55'b0000000000000000000000000000000000000000000001?????????: diff_shift <= 45;
55'b00000000000000000000000000000000000000000000001????????: diff_shift <= 46;
55'b000000000000000000000000000000000000000000000001???????: diff_shift <= 47;
55'b0000000000000000000000000000000000000000000000001??????: diff_shift <= 48;
55'b00000000000000000000000000000000000000000000000001?????: diff_shift <= 49;
55'b000000000000000000000000000000000000000000000000001????: diff_shift <= 50;
55'b0000000000000000000000000000000000000000000000000001???: diff_shift <= 51;
55'b00000000000000000000000000000000000000000000000000001??: diff_shift <= 52;
55'b000000000000000000000000000000000000000000000000000001?: diff_shift <= 53;
55'b0000000000000000000000000000000000000000000000000000001: diff_shift <= 54;
55'b0000000000000000000000000000000000000000000000000000000: diff_shift <= 55;
endcase
 
always @(posedge clk)
begin
if (rst) begin
ready <= 0;
count_ready_0 <= 0;
count_ready <= 0;
end
else if (enable) begin
ready <= count_ready;
count_ready_0 <= count == 21;
count_ready <= count == 22;
end
end
 
always @(posedge clk)
begin
if (rst)
count <= 0;
else if (enable & !count_ready_0 & !count_ready)
count <= count + 1;
end
 
always @(posedge clk)
begin
if (rst)
out <= 0;
else if (enable & count_ready)
out <= in_inf21 ? { outfp[63], 11'b11111111111, 52'b0 } : outfp;
end
endmodule
/fpu_mul_TB.v
0,0 → 1,168
 
`timescale 1ps / 1ps
module fpu_mul_tb;
 
reg clk;
reg rst;
reg enable;
reg [1:0]rmode;
reg [63:0]opa;
reg [63:0]opb;
wire ready;
wire [63:0]outfp;
 
fpu_mul UUT (
.clk(clk),
.rst(rst),
.enable(enable),
.rmode(rmode),
.opa(opa),
.opb(opb),
.ready(ready),
.outfp(outfp));
 
initial
begin : STIMUL
#0
enable = 1'b0;
rst = 1'b1;
#10000; //0
enable = 1'b1;
rst = 1'b0;
//inputA:9.6300000000e+001
//inputB:-2.5600000000e-001
opa = 64'b0100000001011000000100110011001100110011001100110011001100110011;
opb = 64'b1011111111010000011000100100110111010010111100011010100111111100;
rmode = 2'b11;
#10000;
//inputA:3.6600000000e+000
//inputB:2.2500000000e+000
opa = 64'b0100000000001101010001111010111000010100011110101110000101001000;
opb = 64'b0100000000000010000000000000000000000000000000000000000000000000;
rmode = 2'b00;
#10000;
//inputA:-5.6970000000e+001
//inputB:1.2340000000e-001
opa = 64'b1100000001001100011111000010100011110101110000101000111101011100;
opb = 64'b0011111110111111100101110010010001110100010100111000111011110011;
rmode = 2'b11;
#10000;
//inputA:4.5680000000e+001
//inputB:2.1300000000e+000
opa = 64'b0100000001000110110101110000101000111101011100001010001111010111;
opb = 64'b0100000000000001000010100011110101110000101000111101011100001010;
rmode = 2'b00;
#10000;
//inputA:3.0000000000e-311
//inputB:-4.0000000000e+060
opa = 64'b0000000000000000000001011000010111000011011011101010101101110011;
opb = 64'b1100110010000011111010011110010011100100110000101111001101000100;
rmode = 2'b10;
#10000;
//inputA:4.6300000000e+001
//inputB:2.3110000000e+001
opa = 64'b0100000001000111001001100110011001100110011001100110011001100110;
opb = 64'b0100000000110111000111000010100011110101110000101000111101011100;
rmode = 2'b00;
#10000;
//inputA:5.0000000000e-250
//inputB:-1.#INF000000e+000
opa = 64'b0000110000101100101000111000111100110101000010110010001011011111;
opb = 64'b1111111111110000000000000000000000000000000000000000000000000000;
rmode = 2'b11;
#10000;
//inputA:
//inputB:
opa = 64'b0100000000111111111111111111111111111111111111111111111111111110;
opb = 64'b0100000000110000000000000000000000000000000000000000000000000001;
rmode = 2'b00;
#10000;
//inputA:1.2000000000e-001
//inputB:5.2000000000e+001
opa = 64'b0011111110111110101110000101000111101011100001010001111010111000;
opb = 64'b0100000001001010000000000000000000000000000000000000000000000000;
rmode = 2'b00;
#10000;
//inputA:8.9999000000e+004
//inputB:1.6000000000e+001
opa = 64'b0100000011110101111110001111000000000000000000000000000000000000;
opb = 64'b0100000000110000000000000000000000000000000000000000000000000000;
rmode = 2'b10;
 
#120000;
//Output:-2.465280000000000e+001
if (outfp==64'hC038A71DE69AD42D)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:8.235000000000001e+000
if (outfp==64'h40207851EB851EB8)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:-7.030098000000000e+000
if (outfp==64'hC01C1ED20296B335)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:9.729840000000000e+001
if (outfp==64'h40585318FC504817)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:-0
if (outfp==64'h8000000000000000)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:1.069993000000000e+003
if (outfp==64'h4090B7F8D4FDF3B6)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:-INF
if (outfp==64'hFFF0000000000000)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output
if (outfp==64'h4080000000000000)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:6.240000000000000e+000
if (outfp==64'h4018F5C28F5C28F6)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
#10000; //0
//Output:1.439984000000000e+006
if (outfp==64'h4135F8F000000000)
$display($time,"ps Answer is correct %h", outfp);
else
$display($time,"ps Error! out is incorrect %h", outfp);
 
#290000; //10000
$finish;
end // end of stimulus process
always
begin : CLOCK_clk
 
clk = 1'b0;
#5000;
clk = 1'b1;
#5000;
end
 
 
endmodule
/fpu_addsub_TB.v
0,0 → 1,254
 
`timescale 1ps / 1ps
module fpu_addsub_tb;
 
reg clk;
reg rst;
reg enable;
reg fpu_op;
reg [1:0]rmode;
reg [63:0]opa;
reg [63:0]opb;
wire [63:0]out;
wire ready;
 
 
fpu_addsub UUT (
.clk(clk),
.rst(rst),
.enable(enable),
.fpu_op(fpu_op),
.rmode(rmode),
.opa(opa),
.opb(opb),
.out(out),
.ready(ready));
 
initial
begin : STIMUL
#0
enable = 1'b0;
rst = 1'b1;
#10000;
enable = 1'b1;
rst = 1'b0;
opa = 64'b0100000000010001010110010001011010000111001010110000001000001100;
opb = 64'b0000110000000110111010010011111101011101101000101000001001001100;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:1.6000000000e+001
//inputB:1.0000000000e-208
opa = 64'b0100000000110000000000000000000000000000000000000000000000000000;
opb = 64'b0001010011000000011100000001101111010101001001111011010010011000;
fpu_op = 1'b1;
rmode = 2'b10;
#10000;
//inputA:9.9999999996e-314
//inputB:4.6770000000e+000
opa = 64'b0000000000000000000000000000010010110110011010010101010000110010;
opb = 64'b0100000000010010101101010011111101111100111011011001000101101000;
fpu_op = 1'b1;
rmode = 2'b11;
#10000;
//inputA:5.3620000000e+003
//inputB:1.9999999999e-314
opa = 64'b0100000010110100111100100000000000000000000000000000000000000000;
opb = 64'b0000000000000000000000000000000011110001010010000100010000001010;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:5.8000000000e+000
//inputB:5.7900000000e+000
opa = 64'b0100000000010111001100110011001100110011001100110011001100110011;
opb = 64'b0100000000010111001010001111010111000010100011110101110000101001;
fpu_op = 1'b1;
rmode = 2'b10;
#10000;
opa = 64'b0100000000010001010110010001011010000111001010110000001000001100;
opb = 64'b0000110000000110111010010011111101011101101000101000001001001100;
fpu_op = 1'b0;
rmode = 2'b00;
#10000;
//inputA:-9.4000000000e+035
//inputB:9.4770000000e+035
opa = 64'b1100011101100110101000010011001010000000011101101111101100010011;
opb = 64'b0100011101100110110100001010011011110101101100101001000000100011;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:-3.6680000000e+000
//inputB:9.0007340000e+003
opa = 64'b1100000000001101010110000001000001100010010011011101001011110010;
opb = 64'b0100000011000001100101000101110111110011101101100100010110100010;
fpu_op = 1'b1;
rmode = 2'b11;
#10000;
//inputA:4.7700000000e+000
//inputB:-2.5000000000e-003
opa = 64'b0100000000010011000101000111101011100001010001111010111000010100;
opb = 64'b1011111101100100011110101110000101000111101011100001010001111011;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:7.9500000000e+000
//inputB:-7.9433210000e+000
opa = 64'b0100000000011111110011001100110011001100110011001100110011001101;
opb = 64'b1100000000011111110001011111010111110000101100101000010100100011;
fpu_op = 1'b1;
rmode = 2'b00;
#10000;
//inputA:8.0260000000e+000
//inputB:1.0000000000e-106
opa = 64'b0100000000100000000011010100111111011111001110110110010001011010;
opb = 64'b0010100111101101010110110101011000010101011101000111011001011011;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:9.9230000000e+001
//inputB:2.5370000000e-003
opa = 64'b0100000001011000110011101011100001010001111010111000010100011111;
opb = 64'b0011111101100100110010000111100110000000111101010101110111100110;
fpu_op = 1'b1;
rmode = 2'b11;
#10000;
//inputA:1.7179869184e+010
//inputB:4.0000000000e-176
opa = 64'b0100001000001111111111111111111111111111111111111111111111111111;
opb = 64'b0001101110000100010000101110010011111011011001110001100101100000;
fpu_op = 1'b0;
rmode = 2'b10;
#10000;
//inputA:-2.6800000000e-005
//inputB:-8.5400000000e-013
opa = 64'b1011111011111100000110100001000111111001111111011000011110000000;
opb = 64'b1011110101101110000011000010010111101110000010111101110010010110;
fpu_op = 1'b0;
rmode = 2'b00;
#10000;
//inputA:-8.5400000000e-013
//inputB:INF
opa = 64'b1011110101101110000011000010010111101110000010111101110010010110;
opb = 64'b0111111111110000000000000000000000000000000000000000000000000000;
fpu_op = 1'b0;
rmode = 2'b00;
#10000;
//inputA:-5.6555650000e+006
//inputB:-2.3665000000e-001
opa = 64'b1100000101010101100100110000001101000000000000000000000000000000;
opb = 64'b1011111111001110010010101000110000010101010011001001100001011111;
fpu_op = 1'b1;
rmode = 2'b11;
#90000;
//Output:4.337000000000001e+000
if (out==64'h40115916872B020D)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:1.600000000000000e+001
if (out==64'h4030000000000000)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:-4.677000000000000e+000
if (out==64'hC012B53F7CED9168)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:5.362000000000001e+003
if (out==64'h40B4F20000000000)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:9.999999999999787e-003
if (out==64'h3F847AE147AE1400)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:4.337000000000001e+000
if (out==64'h40115916872B020C)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:7.699999999999867e+033
if (out==64'h46F7BA3A9DCA8800)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:-9.004402000000000e+003
if (out==64'hC0C1963374BC6A80)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:4.767500000000000e+000
if (out==64'h401311EB851EB852)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:1.589332100000000e+001
if (out==64'h402FC9615EBFA8F8)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:8.026000000000002e+000
if (out==64'h40200D4FDF3B645B)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:9.922746300000000e+001
if (out==64'h4058CE8EC0F88334)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:1.717986918400000e+010
if (out==64'h4210000000000000)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:-2.680000085400000e-005
if (out==64'hBEFC1A1209039A77)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:INF
if (out==64'h7FF0000000000000)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#10000;
//Output:-5.655564763350001e+006
if (out==64'hC155930330DAB9F6)
$display($time,"ps Answer is correct %h", out);
else
$display($time,"ps Error! out is incorrect %h", out);
#390000;
$finish;
end
always
begin : CLOCK_clk
clk = 1'b0;
#5000;
clk = 1'b1;
#5000;
end
endmodule
/fpu_mul.v
0,0 → 1,270
/////////////////////////////////////////////////////////////////////
//// ////
//// FPU ////
//// Floating Point Unit (Double precision) ////
//// ////
//// Author: David Lundgren ////
//// davidklun@gmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 David Lundgren ////
//// davidklun@gmail.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
// rmode = 00 (nearest), 01 (to zero), 10 (+ infinity), 11 (- infinity)
 
`timescale 1ns / 100ps
 
module fpu_mul( clk, rst, enable, rmode, opa, opb, ready, outfp);
input clk;
input rst;
input enable;
input [1:0] rmode;
input [63:0] opa, opb;
output ready;
output [63:0] outfp;
 
 
reg product_shift;
reg [1:0] rm_1, rm_2, rm_3, rm_4, rm_5, rm_6, rm_7, rm_8, rm_9;
reg [1:0] rm_10, rm_11, rm_12, rm_13, rm_14, rm_15;
reg sign, sign_1, sign_2, sign_3, sign_4, sign_5, sign_6, sign_7, sign_8;
reg sign_9, sign_10, sign_11, sign_12, sign_13, sign_14, sign_15, sign_16, sign_17;
reg sign_18, sign_19, sign_20;
reg [51:0] mantissa_a1, mantissa_a2;
reg [51:0] mantissa_b1, mantissa_b2;
reg [10:0] exponent_a;
reg [10:0] exponent_b;
reg ready, count_ready, count_ready_0;
reg [4:0] count;
reg a_is_zero, b_is_zero, a_is_inf, b_is_inf, in_inf_1, in_inf_2;
reg in_zero_1;
reg [11:0] exponent_terms_1, exponent_terms_2, exponent_terms_3, exponent_terms_4;
reg [11:0] exponent_terms_5, exponent_terms_6, exponent_terms_7;
reg [11:0] exponent_terms_8, exponent_terms_9;
reg exponent_gt_expoffset;
reg [11:0] exponent_1;
wire [11:0] exponent = 0;
reg [11:0] exponent_2, exponent_2_0, exponent_2_1;
reg exponent_gt_prodshift, exponent_is_infinity;
reg [11:0] exponent_3, exponent_4;
reg set_mantissa_zero, set_mz_1;
reg [52:0] mul_a, mul_a1, mul_a2, mul_a3, mul_a4, mul_a5, mul_a6, mul_a7, mul_a8;
reg [52:0] mul_b, mul_b1, mul_b2, mul_b3, mul_b4, mul_b5, mul_b6, mul_b7, mul_b8;
reg [40:0] product_a;
reg [16:0] product_a_2, product_a_3, product_a_4, product_a_5, product_a_6;
reg [16:0] product_a_7, product_a_8, product_a_9, product_a_10;
reg [40:0] product_b;
reg [40:0] product_c;
reg [25:0] product_d;
reg [33:0] product_e;
reg [33:0] product_f;
reg [35:0] product_g;
reg [28:0] product_h;
reg [28:0] product_i;
reg [30:0] product_j;
reg [41:0] sum_0;
reg [6:0] sum_0_2, sum_0_3, sum_0_4, sum_0_5, sum_0_6, sum_0_7, sum_0_8, sum_0_9;
reg [35:0] sum_1;
reg [9:0] sum_1_2, sum_1_3, sum_1_4, sum_1_5, sum_1_6, sum_1_7, sum_1_8;
reg [41:0] sum_2;
reg [6:0] sum_2_2, sum_2_3, sum_2_4, sum_2_5, sum_2_6, sum_2_7;
reg [35:0] sum_3;
reg [36:0] sum_4;
reg [9:0] sum_4_2, sum_4_3, sum_4_4, sum_4_5;
reg [27:0] sum_5;
reg [6:0] sum_5_2, sum_5_3, sum_5_4;
reg [29:0] sum_6;
reg [36:0] sum_7;
reg [16:0] sum_7_2;
reg [30:0] sum_8;
reg [105:0] product;
reg [105:0] product_1;
reg [52:0] product_2, product_3;
reg [53:0] product_4, product_5, product_6, product_7;
reg product_overflow;
reg [11:0] exponent_5, exponent_6, exponent_7, exponent_8, exponent_9;
reg round_nearest_mode, round_posinf_mode, round_neginf_mode;
reg round_nearest_trigger, round_nearest_exception;
reg round_nearest_enable, round_posinf_trigger, round_posinf_enable;
reg round_neginf_trigger, round_neginf_enable, round_enable;
wire [63:0] outfp = { sign, exponent_9[10:0], product_7[51:0]};
 
always @(posedge clk)
begin
if (rst) begin
sign <= 0; sign_1 <= 0; sign_2 <= 0; sign_3 <= 0; sign_4 <= 0;
sign_5 <= 0; sign_6 <= 0; sign_7 <= 0; sign_8 <= 0; sign_9 <= 0;
sign_10 <= 0; sign_11 <= 0; sign_12 <= 0; sign_13 <= 0;
sign_14 <= 0; sign_15 <= 0; sign_16 <= 0; sign_17 <= 0; sign_18 <= 0; sign_19 <= 0;
sign_20 <= 0; mantissa_a1 <= 0; mantissa_b1 <= 0; mantissa_a2 <= 0; mantissa_b2 <= 0;
exponent_a <= 0; exponent_b <= 0; rm_1 <= 0; rm_2 <= 0; rm_3 <= 0; rm_4 <= 0; rm_5 <= 0;
rm_6 <= 0; rm_7 <= 0; rm_8 <= 0; rm_9 <= 0; rm_10 <= 0; rm_11 <= 0;
rm_12 <= 0; rm_13 <= 0; rm_14 <= 0; rm_15 <= 0;
a_is_zero <= 0; b_is_zero <= 0; a_is_inf <= 0; b_is_inf <= 0; in_inf_1 <= 0; in_inf_2 <= 0;
in_zero_1 <= 0; exponent_terms_1 <= 0; exponent_terms_2 <= 0; exponent_terms_3 <= 0;
exponent_terms_4 <= 0; exponent_terms_5 <= 0; exponent_terms_6 <= 0; exponent_terms_7 <= 0;
exponent_terms_8 <= 0; exponent_terms_9 <= 0; exponent_gt_expoffset <= 0; exponent_1 <= 0;
exponent_2_0 <= 0; exponent_2_1 <= 0; exponent_2 <= 0; exponent_gt_prodshift <= 0;
exponent_is_infinity <= 0; exponent_3 <= 0; exponent_4 <= 0;
set_mantissa_zero <= 0; set_mz_1 <= 0; mul_a <= 0; mul_b <= 0; mul_a1 <= 0; mul_b1 <= 0;
mul_a2 <= 0; mul_b2 <= 0; mul_a3 <= 0; mul_b3 <= 0; mul_a4 <= 0; mul_b4 <= 0; mul_a5 <= 0;
mul_b5 <= 0; mul_a6 <= 0; mul_b6 <= 0; mul_a7 <= 0; mul_b7 <= 0; mul_a8 <= 0; mul_b8 <= 0;
product_a <= 0; product_a_2 <= 0; product_a_3 <= 0; product_a_4 <= 0; product_a_5 <= 0;
product_a_6 <= 0; product_a_7 <= 0; product_a_8 <= 0; product_a_9 <= 0; product_a_10 <= 0;
product_b <= 0; product_c <= 0; product_d <= 0; product_e <= 0; product_f <= 0;
product_g <= 0; product_h <= 0; product_i <= 0; product_j <= 0;
sum_0 <= 0; sum_0_2 <= 0; sum_0_3 <= 0; sum_0_4 <= 0; sum_0_5 <= 0; sum_0_6 <= 0;
sum_0_7 <= 0; sum_0_8 <= 0; sum_0_9 <= 0; sum_1 <= 0; sum_1_2 <= 0; sum_1_3 <= 0; sum_1_4 <= 0;
sum_1_5 <= 0; sum_1_6 <= 0; sum_1_7 <= 0; sum_1_8 <= 0; sum_2 <= 0; sum_2_2 <= 0; sum_2_3 <= 0;
sum_2_4 <= 0; sum_2_5 <= 0; sum_2_6 <= 0; sum_2_7 <= 0; sum_3 <= 0; sum_4 <= 0; sum_4_2 <= 0;
sum_4_3 <= 0; sum_4_4 <= 0; sum_4_5 <= 0; sum_5 <= 0; sum_5_2 <= 0; sum_5_3 <= 0; sum_5_4 <= 0;
sum_6 <= 0; sum_7 <= 0; sum_7_2 <= 0; sum_8 <= 0; product <= 0; product_1 <= 0; product_2 <= 0;
product_3 <= 0; product_4 <= 0; product_5 <= 0; product_overflow <= 0; product_6 <= 0;
exponent_5 <= 0; exponent_6 <= 0; exponent_7 <= 0; exponent_8 <= 0; product_shift <= 0;
product_7 <= 0; exponent_9 <= 0;
round_nearest_mode <= 0; round_posinf_mode <= 0; round_neginf_mode <= 0; round_nearest_trigger <= 0;
round_nearest_exception <= 0; round_nearest_enable <= 0; round_posinf_trigger <= 0; round_posinf_enable <= 0;
round_neginf_trigger <= 0; round_neginf_enable <= 0; round_enable <= 0;
end
else if (enable) begin
sign_1 <= opa[63] ^ opb[63]; sign_2 <= sign_1; sign_3 <= sign_2; sign_4 <= sign_3;
sign_5 <= sign_4; sign_6 <= sign_5; sign_7 <= sign_6; sign_8 <= sign_7; sign_9 <= sign_8;
sign_10 <= sign_9; sign_11 <= sign_10; sign_12 <= sign_11; sign_13 <= sign_12;
sign_14 <= sign_13; sign_15 <= sign_14; sign_16 <= sign_15; sign_17 <= sign_16;
sign_18 <= sign_17; sign_19 <= sign_18; sign_20 <= sign_19; sign <= sign_20;
mantissa_a1 <= opa[51:0]; mantissa_b1 <= opb[51:0]; mantissa_a2 <= mantissa_a1;
mantissa_b2 <= mantissa_b1; exponent_a <= opa[62:52]; exponent_b <= opb[62:52];
rm_1 <= rmode; rm_2 <= rm_1; rm_3 <= rm_2; rm_4 <= rm_3;
rm_5 <= rm_4; rm_6 <= rm_5; rm_7 <= rm_6; rm_8 <= rm_7; rm_9 <= rm_8;
rm_10 <= rm_9; rm_11 <= rm_10; rm_12 <= rm_11; rm_13 <= rm_12; rm_14 <= rm_13;
rm_15 <= rm_14;
a_is_zero <= !(|exponent_a); b_is_zero <= !(|exponent_b);
a_is_inf <= exponent_a == 2047; b_is_inf <= exponent_b == 2047;
in_inf_1 <= a_is_inf | b_is_inf; in_inf_2 <= in_inf_1;
in_zero_1 <= a_is_zero | b_is_zero;
exponent_terms_1 <= exponent_a + exponent_b;
exponent_terms_2 <= exponent_terms_1;
exponent_terms_3 <= in_zero_1 ? 12'b0 : exponent_terms_2;
exponent_terms_4 <= in_inf_2 ? 12'b110000000000 : exponent_terms_3;
exponent_terms_5 <= exponent_terms_4; exponent_terms_6 <= exponent_terms_5;
exponent_terms_7 <= exponent_terms_6; exponent_terms_8 <= exponent_terms_7;
exponent_terms_9 <= exponent_terms_8;
exponent_gt_expoffset <= exponent_terms_9 > 1022;
exponent_1 <= exponent_terms_9 - 1022;
exponent_2_0 <= exponent_gt_expoffset ? exponent_1 : exponent;
exponent_2_1 <= exponent_2_0;
exponent_2 <= exponent_2_1;
exponent_is_infinity <= (exponent_3 > 2046) & exponent_gt_prodshift;
exponent_3 <= exponent_2 - product_shift;
exponent_gt_prodshift <= exponent_2 >= product_shift;
exponent_4 <= exponent_gt_prodshift ? exponent_3 : exponent;
exponent_5 <= exponent_is_infinity ? 12'b011111111111 : exponent_4;
set_mantissa_zero <= exponent_4 == 0 | exponent_is_infinity;
set_mz_1 <= set_mantissa_zero;
exponent_6 <= exponent_5;
mul_a <= { !a_is_zero, mantissa_a2 }; mul_b <= { !b_is_zero, mantissa_b2 };
mul_a1 <= mul_a; mul_b1 <= mul_b;
mul_a2 <= mul_a1; mul_b2 <= mul_b1; mul_a3 <= mul_a2; mul_b3 <= mul_b2;
mul_a4 <= mul_a3; mul_b4 <= mul_b3; mul_a5 <= mul_a4; mul_b5 <= mul_b4;
mul_a6 <= mul_a5; mul_b6 <= mul_b5; mul_a7 <= mul_a6; mul_b7 <= mul_b6;
mul_a8 <= mul_a7; mul_b8 <= mul_b7;
product_a <= mul_a[23:0] * mul_b[16:0]; product_a_2 <= product_a[16:0];
product_a_3 <= product_a_2; product_a_4 <= product_a_3; product_a_5 <= product_a_4;
product_a_6 <= product_a_5; product_a_7 <= product_a_6; product_a_8 <= product_a_7;
product_a_9 <= product_a_8; product_a_10 <= product_a_9;
product_b <= mul_a[23:0] * mul_b[33:17];
product_c <= mul_a2[23:0] * mul_b2[50:34];
product_d <= mul_a5[23:0] * mul_b5[52:51];
product_e <= mul_a1[40:24] * mul_b1[16:0];
product_f <= mul_a4[40:24] * mul_b4[33:17];
product_g <= mul_a7[40:24] * mul_b7[52:34];
product_h <= mul_a3[52:41] * mul_b3[16:0];
product_i <= mul_a6[52:41] * mul_b6[33:17];
product_j <= mul_a8[52:41] * mul_b8[52:34];
sum_0 <= product_a[40:17] + product_b; sum_0_2 <= sum_0[6:0]; sum_0_3 <= sum_0_2;
sum_0_4 <= sum_0_3; sum_0_5 <= sum_0_4; sum_0_6 <= sum_0_5; sum_0_7 <= sum_0_6;
sum_0_8 <= sum_0_7; sum_0_9 <= sum_0_8;
sum_1 <= sum_0[41:7] + product_e; sum_1_2 <= sum_1[9:0]; sum_1_3 <= sum_1_2;
sum_1_4 <= sum_1_3; sum_1_5 <= sum_1_4; sum_1_6 <= sum_1_5; sum_1_7 <= sum_1_6;
sum_1_8 <= sum_1_7;
sum_2 <= sum_1[35:10] + product_c; sum_2_2 <= sum_2[6:0]; sum_2_3 <= sum_2_2;
sum_2_4 <= sum_2_3; sum_2_5 <= sum_2_4; sum_2_6 <= sum_2_5; sum_2_7 <= sum_2_6;
sum_3 <= sum_2[41:7] + product_h;
sum_4 <= sum_3 + product_f; sum_4_2 <= sum_4[9:0]; sum_4_3 <= sum_4_2;
sum_4_4 <= sum_4_3; sum_4_5 <= sum_4_4;
sum_5 <= sum_4[36:10] + product_d; sum_5_2 <= sum_5[6:0];
sum_5_3 <= sum_5_2; sum_5_4 <= sum_5_3;
sum_6 <= sum_5[27:7] + product_i;
sum_7 <= sum_6 + product_g; sum_7_2 <= sum_7[16:0];
sum_8 <= sum_7[36:17] + product_j;
product <= { sum_8, sum_7_2[16:0], sum_5_4[6:0], sum_4_5[9:0], sum_2_7[6:0],
sum_1_8[9:0], sum_0_9[6:0], product_a_10[16:0] };
product_1 <= product << product_shift;
product_2 <= product_1[105:53]; product_3 <= product_2;
product_4 <= set_mantissa_zero ? 54'b0 : { 1'b0, product_3};
product_shift <= !sum_8[30];
round_nearest_mode <= rm_15 == 2'b00;
round_posinf_mode <= rm_15 == 2'b10;
round_neginf_mode <= rm_15 == 2'b11;
round_nearest_trigger <= product_1[52];
round_nearest_exception <= !(|product_1[51:0]) & (product_1[53] == 0);
round_nearest_enable <= round_nearest_mode & round_nearest_trigger & !round_nearest_exception;
round_posinf_trigger <= |product_1[52:0] & !sign_15;
round_posinf_enable <= round_posinf_mode & round_posinf_trigger;
round_neginf_trigger <= |product_1[52:0] & sign_15;
round_neginf_enable <= round_neginf_mode & round_neginf_trigger;
round_enable <= round_posinf_enable | round_neginf_enable | round_nearest_enable;
product_5 <= round_enable & !set_mz_1 ? product_4 + 1 : product_4;
product_overflow <= product_5[53];
product_6 <= product_5;
product_7 <= product_overflow ? product_6 >> 1 : product_6;
exponent_7 <= exponent_6; exponent_8 <= exponent_7;
exponent_9 <= product_overflow ? exponent_8 + 1 : exponent_8;
end
end
 
always @(posedge clk)
begin
if (rst) begin
ready <= 0;
count_ready_0 <= 0;
count_ready <= 0;
end
else if (enable) begin
ready <= count_ready;
count_ready_0 <= count == 18;
count_ready <= count == 19;
end
end
 
always @(posedge clk)
begin
if (rst)
count <= 0;
else if (enable & !count_ready_0 & !count_ready)
count <= count + 1;
end
 
endmodule

powered by: WebSVN 2.1.0

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