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
    /
    from Rev 11 to Rev 12
    Reverse comparison

Rev 11 → Rev 12

/tags/arelease/fpu_div.v
0,0 → 1,412
/////////////////////////////////////////////////////////////////////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 100ps
 
module fpu_div( clk, rst, enable, opa, opb, sign, mantissa_7,
exponent_out);
input clk;
input rst;
input enable;
input [63:0] opa;
input [63:0] opb;
output sign;
output [55:0] mantissa_7;
output [11:0] exponent_out;
 
parameter preset = 53;
 
reg [53:0] dividend_reg;
reg [53:0] divisor_reg;
reg enable_reg;
reg enable_reg_2;
reg enable_reg_a;
reg enable_reg_b;
reg enable_reg_c;
reg enable_reg_d;
reg enable_reg_e;
reg [5:0] dividend_shift;
reg [5:0] dividend_shift_2;
reg [5:0] divisor_shift;
reg [5:0] divisor_shift_2;
reg [5:0] count_out;
reg [11:0] exponent_out;
 
 
wire sign = opa[63] ^ opb[63];
reg [51:0] mantissa_a;
reg [51:0] mantissa_b;
wire [10:0] expon_a = opa[62:52];
wire [10:0] expon_b = opb[62:52];
wire a_is_norm = |expon_a;
wire b_is_norm = |expon_b;
wire a_is_zero = !(|opa[62:0]);
wire [11:0] exponent_a = { 1'b0, expon_a};
wire [11:0] exponent_b = { 1'b0, expon_b};
reg [51:0] dividend_a;
reg [51:0] dividend_a_shifted;
wire [52:0] dividend_denorm = { dividend_a_shifted, 1'b0};
wire [53:0] dividend_1 = a_is_norm ? { 2'b01, dividend_a } : { 1'b0, dividend_denorm};
reg [51:0] divisor_b;
reg [51:0] divisor_b_shifted;
wire [52:0] divisor_denorm = { divisor_b_shifted, 1'b0};
wire [53:0] divisor_1 = b_is_norm ? { 2'b01, divisor_b } : { 1'b0, divisor_denorm};
wire [5:0] count_index = count_out;
wire count_nonzero = !(count_index == 0);
reg [53:0] quotient;
reg [53:0] quotient_out;
reg [53:0] remainder;
reg [53:0] remainder_out;
reg remainder_msb;
reg count_nonzero_reg;
reg count_nonzero_reg_2;
reg [11:0] expon_term;
reg expon_uf_1;
reg [11:0] expon_uf_term_1;
reg [11:0] expon_final_1;
reg [11:0] expon_final_2;
reg [11:0] expon_shift_a;
reg [11:0] expon_shift_b;
reg expon_uf_2;
reg [11:0] expon_uf_term_2;
reg [11:0] expon_uf_term_3;
reg expon_uf_gt_maxshift;
reg [11:0] expon_uf_term_4;
reg [11:0] expon_final_3;
reg [11:0] expon_final_4;
wire quotient_msb = quotient_out[53];
reg expon_final_4_et0;
reg expon_final_4_term;
reg [11:0] expon_final_5;
reg [51:0] mantissa_1;
wire [51:0] mantissa_2 = quotient_out[52:1];
wire [51:0] mantissa_3 = quotient_out[51:0];
wire [51:0] mantissa_4 = quotient_msb ? mantissa_2 : mantissa_3;
wire [51:0] mantissa_5 = (expon_final_4 == 1) ? mantissa_2 : mantissa_4;
wire [51:0] mantissa_6 = expon_final_4_et0 ? mantissa_1 : mantissa_5;
wire [107:0] remainder_a = { quotient_out[53:0] , remainder_msb, remainder_out[52:0]};
reg [6:0] remainder_shift_term;
reg [107:0] remainder_b;
wire [55:0] remainder_1 = remainder_b[107:52];
wire [55:0] remainder_2 = { quotient_out[0] , remainder_msb, remainder_out[52:0], 1'b0 };
wire [55:0] remainder_3 = { remainder_msb , remainder_out[52:0], 2'b0 };
wire [55:0] remainder_4 = quotient_msb ? remainder_2 : remainder_3;
wire [55:0] remainder_5 = (expon_final_4 == 1) ? remainder_2 : remainder_4;
wire [55:0] remainder_6 = expon_final_4_et0 ? remainder_1 : remainder_5;
wire m_norm = |expon_final_5;
wire rem_lsb = |remainder_6[54:0];
wire [55:0] mantissa_7 = { 1'b0, m_norm, mantissa_6, remainder_6[55], rem_lsb };
 
always @ (posedge clk)
begin
if (rst)
exponent_out <= 0;
else
exponent_out <= a_is_zero ? 12'b0 : expon_final_5;
end
 
always @ (posedge clk)
begin
if (rst)
count_out <= 0;
else if (enable_reg)
count_out <= preset;
else if (count_nonzero)
count_out <= count_out - 1;
end
 
always @ (posedge clk)
begin
if (rst) begin
quotient_out <= 0;
remainder_out <= 0;
end
else begin
quotient_out <= quotient;
remainder_out <= remainder;
end
end
 
 
always @ (posedge clk)
begin
if (rst)
quotient <= 0;
else if (count_nonzero_reg)
quotient[count_index] <= !(divisor_reg > dividend_reg);
end
 
always @ (posedge clk)
begin
if (rst) begin
remainder <= 0;
remainder_msb <= 0;
end
else if (!count_nonzero_reg & count_nonzero_reg_2) begin
remainder <= dividend_reg;
remainder_msb <= (divisor_reg > dividend_reg) ? 0 : 1;
end
end
 
always @ (posedge clk)
begin
if (rst) begin
dividend_reg <= 0;
divisor_reg <= 0;
end
else if (enable_reg_e) begin
dividend_reg <= dividend_1;
divisor_reg <= divisor_1;
end
else if (count_nonzero_reg)
dividend_reg <= (divisor_reg > dividend_reg) ? dividend_reg << 1 :
(dividend_reg - divisor_reg) << 1;
// divisor doesn't change for the divide
end
 
always @ (posedge clk)
begin
if (rst) begin
expon_term <= 0;
expon_uf_1 <= 0;
expon_uf_term_1 <= 0;
expon_final_1 <= 0;
expon_final_2 <= 0;
expon_shift_a <= 0;
expon_shift_b <= 0;
expon_uf_2 <= 0;
expon_uf_term_2 <= 0;
expon_uf_term_3 <= 0;
expon_uf_gt_maxshift <= 0;
expon_uf_term_4 <= 0;
expon_final_3 <= 0;
expon_final_4 <= 0;
expon_final_4_et0 <= 0;
expon_final_4_term <= 0;
expon_final_5 <= 0;
mantissa_a <= 0;
mantissa_b <= 0;
dividend_a <= 0;
divisor_b <= 0;
dividend_shift_2 <= 0;
divisor_shift_2 <= 0;
remainder_shift_term <= 0;
remainder_b <= 0;
dividend_a_shifted <= 0;
divisor_b_shifted <= 0;
mantissa_1 <= 0;
end
else if (enable_reg_2) begin
expon_term <= exponent_a + 1023;
expon_uf_1 <= exponent_b > expon_term;
expon_uf_term_1 <= expon_uf_1 ? (exponent_b - expon_term) : 0;
expon_final_1 <= expon_term - exponent_b;
expon_final_2 <= expon_uf_1 ? 0 : expon_final_1;
expon_shift_a <= a_is_norm ? 0 : dividend_shift_2;
expon_shift_b <= b_is_norm ? 0 : divisor_shift_2;
expon_uf_2 <= expon_shift_a > expon_final_2;
expon_uf_term_2 <= expon_uf_2 ? (expon_shift_a - expon_final_2) : 0;
expon_uf_term_3 <= expon_uf_term_2 + expon_uf_term_1;
expon_uf_gt_maxshift <= (expon_uf_term_3 > 51);
expon_uf_term_4 <= expon_uf_gt_maxshift ? 52 : expon_uf_term_3;
expon_final_3 <= expon_uf_2 ? 0 : (expon_final_2 - expon_shift_a);
expon_final_4 <= expon_final_3 + expon_shift_b;
expon_final_4_et0 <= (expon_final_4 == 0);
expon_final_4_term <= expon_final_4_et0 ? 0 : 1;
expon_final_5 <= quotient_msb ? expon_final_4 : expon_final_4 - expon_final_4_term;
mantissa_a <= opa[51:0];
mantissa_b <= opb[51:0];
dividend_a <= mantissa_a;
divisor_b <= mantissa_b;
dividend_shift_2 <= dividend_shift;
divisor_shift_2 <= divisor_shift;
remainder_shift_term <= 52 - expon_uf_term_4;
remainder_b <= remainder_a << remainder_shift_term;
dividend_a_shifted <= dividend_a << dividend_shift_2;
divisor_b_shifted <= divisor_b << divisor_shift_2;
mantissa_1 <= quotient_out[53:2] >> expon_uf_term_4;
end
end
 
always @ (posedge clk)
begin
if (rst) begin
count_nonzero_reg <= 0;
count_nonzero_reg_2 <= 0;
enable_reg <= 0;
enable_reg_a <= 0;
enable_reg_b <= 0;
enable_reg_c <= 0;
enable_reg_d <= 0;
enable_reg_e <= 0;
end
else begin
count_nonzero_reg <= count_nonzero;
count_nonzero_reg_2 <= count_nonzero_reg;
enable_reg <= enable_reg_e;
enable_reg_a <= enable;
enable_reg_b <= enable_reg_a;
enable_reg_c <= enable_reg_b;
enable_reg_d <= enable_reg_c;
enable_reg_e <= enable_reg_d;
end
end
 
always @ (posedge clk)
begin
if (rst)
enable_reg_2 <= 0;
else if (enable)
enable_reg_2 <= 1;
end
 
 
always @(dividend_a)
casex(dividend_a)
52'b1???????????????????????????????????????????????????: dividend_shift <= 0;
52'b01??????????????????????????????????????????????????: dividend_shift <= 1;
52'b001?????????????????????????????????????????????????: dividend_shift <= 2;
52'b0001????????????????????????????????????????????????: dividend_shift <= 3;
52'b00001???????????????????????????????????????????????: dividend_shift <= 4;
52'b000001??????????????????????????????????????????????: dividend_shift <= 5;
52'b0000001?????????????????????????????????????????????: dividend_shift <= 6;
52'b00000001????????????????????????????????????????????: dividend_shift <= 7;
52'b000000001???????????????????????????????????????????: dividend_shift <= 8;
52'b0000000001??????????????????????????????????????????: dividend_shift <= 9;
52'b00000000001?????????????????????????????????????????: dividend_shift <= 10;
52'b000000000001????????????????????????????????????????: dividend_shift <= 11;
52'b0000000000001???????????????????????????????????????: dividend_shift <= 12;
52'b00000000000001??????????????????????????????????????: dividend_shift <= 13;
52'b000000000000001?????????????????????????????????????: dividend_shift <= 14;
52'b0000000000000001????????????????????????????????????: dividend_shift <= 15;
52'b00000000000000001???????????????????????????????????: dividend_shift <= 16;
52'b000000000000000001??????????????????????????????????: dividend_shift <= 17;
52'b0000000000000000001?????????????????????????????????: dividend_shift <= 18;
52'b00000000000000000001????????????????????????????????: dividend_shift <= 19;
52'b000000000000000000001???????????????????????????????: dividend_shift <= 20;
52'b0000000000000000000001??????????????????????????????: dividend_shift <= 21;
52'b00000000000000000000001?????????????????????????????: dividend_shift <= 22;
52'b000000000000000000000001????????????????????????????: dividend_shift <= 23;
52'b0000000000000000000000001???????????????????????????: dividend_shift <= 24;
52'b00000000000000000000000001??????????????????????????: dividend_shift <= 25;
52'b000000000000000000000000001?????????????????????????: dividend_shift <= 26;
52'b0000000000000000000000000001????????????????????????: dividend_shift <= 27;
52'b00000000000000000000000000001???????????????????????: dividend_shift <= 28;
52'b000000000000000000000000000001??????????????????????: dividend_shift <= 29;
52'b0000000000000000000000000000001?????????????????????: dividend_shift <= 30;
52'b00000000000000000000000000000001????????????????????: dividend_shift <= 31;
52'b000000000000000000000000000000001???????????????????: dividend_shift <= 32;
52'b0000000000000000000000000000000001??????????????????: dividend_shift <= 33;
52'b00000000000000000000000000000000001?????????????????: dividend_shift <= 34;
52'b000000000000000000000000000000000001????????????????: dividend_shift <= 35;
52'b0000000000000000000000000000000000001???????????????: dividend_shift <= 36;
52'b00000000000000000000000000000000000001??????????????: dividend_shift <= 37;
52'b000000000000000000000000000000000000001?????????????: dividend_shift <= 38;
52'b0000000000000000000000000000000000000001????????????: dividend_shift <= 39;
52'b00000000000000000000000000000000000000001???????????: dividend_shift <= 40;
52'b000000000000000000000000000000000000000001??????????: dividend_shift <= 41;
52'b0000000000000000000000000000000000000000001?????????: dividend_shift <= 42;
52'b00000000000000000000000000000000000000000001????????: dividend_shift <= 43;
52'b000000000000000000000000000000000000000000001???????: dividend_shift <= 44;
52'b0000000000000000000000000000000000000000000001??????: dividend_shift <= 45;
52'b00000000000000000000000000000000000000000000001?????: dividend_shift <= 46;
52'b000000000000000000000000000000000000000000000001????: dividend_shift <= 47;
52'b0000000000000000000000000000000000000000000000001???: dividend_shift <= 48;
52'b00000000000000000000000000000000000000000000000001??: dividend_shift <= 49;
52'b000000000000000000000000000000000000000000000000001?: dividend_shift <= 50;
52'b0000000000000000000000000000000000000000000000000001: dividend_shift <= 51;
52'b0000000000000000000000000000000000000000000000000000: dividend_shift <= 52;
endcase
always @(divisor_b)
casex(divisor_b)
52'b1???????????????????????????????????????????????????: divisor_shift <= 0;
52'b01??????????????????????????????????????????????????: divisor_shift <= 1;
52'b001?????????????????????????????????????????????????: divisor_shift <= 2;
52'b0001????????????????????????????????????????????????: divisor_shift <= 3;
52'b00001???????????????????????????????????????????????: divisor_shift <= 4;
52'b000001??????????????????????????????????????????????: divisor_shift <= 5;
52'b0000001?????????????????????????????????????????????: divisor_shift <= 6;
52'b00000001????????????????????????????????????????????: divisor_shift <= 7;
52'b000000001???????????????????????????????????????????: divisor_shift <= 8;
52'b0000000001??????????????????????????????????????????: divisor_shift <= 9;
52'b00000000001?????????????????????????????????????????: divisor_shift <= 10;
52'b000000000001????????????????????????????????????????: divisor_shift <= 11;
52'b0000000000001???????????????????????????????????????: divisor_shift <= 12;
52'b00000000000001??????????????????????????????????????: divisor_shift <= 13;
52'b000000000000001?????????????????????????????????????: divisor_shift <= 14;
52'b0000000000000001????????????????????????????????????: divisor_shift <= 15;
52'b00000000000000001???????????????????????????????????: divisor_shift <= 16;
52'b000000000000000001??????????????????????????????????: divisor_shift <= 17;
52'b0000000000000000001?????????????????????????????????: divisor_shift <= 18;
52'b00000000000000000001????????????????????????????????: divisor_shift <= 19;
52'b000000000000000000001???????????????????????????????: divisor_shift <= 20;
52'b0000000000000000000001??????????????????????????????: divisor_shift <= 21;
52'b00000000000000000000001?????????????????????????????: divisor_shift <= 22;
52'b000000000000000000000001????????????????????????????: divisor_shift <= 23;
52'b0000000000000000000000001???????????????????????????: divisor_shift <= 24;
52'b00000000000000000000000001??????????????????????????: divisor_shift <= 25;
52'b000000000000000000000000001?????????????????????????: divisor_shift <= 26;
52'b0000000000000000000000000001????????????????????????: divisor_shift <= 27;
52'b00000000000000000000000000001???????????????????????: divisor_shift <= 28;
52'b000000000000000000000000000001??????????????????????: divisor_shift <= 29;
52'b0000000000000000000000000000001?????????????????????: divisor_shift <= 30;
52'b00000000000000000000000000000001????????????????????: divisor_shift <= 31;
52'b000000000000000000000000000000001???????????????????: divisor_shift <= 32;
52'b0000000000000000000000000000000001??????????????????: divisor_shift <= 33;
52'b00000000000000000000000000000000001?????????????????: divisor_shift <= 34;
52'b000000000000000000000000000000000001????????????????: divisor_shift <= 35;
52'b0000000000000000000000000000000000001???????????????: divisor_shift <= 36;
52'b00000000000000000000000000000000000001??????????????: divisor_shift <= 37;
52'b000000000000000000000000000000000000001?????????????: divisor_shift <= 38;
52'b0000000000000000000000000000000000000001????????????: divisor_shift <= 39;
52'b00000000000000000000000000000000000000001???????????: divisor_shift <= 40;
52'b000000000000000000000000000000000000000001??????????: divisor_shift <= 41;
52'b0000000000000000000000000000000000000000001?????????: divisor_shift <= 42;
52'b00000000000000000000000000000000000000000001????????: divisor_shift <= 43;
52'b000000000000000000000000000000000000000000001???????: divisor_shift <= 44;
52'b0000000000000000000000000000000000000000000001??????: divisor_shift <= 45;
52'b00000000000000000000000000000000000000000000001?????: divisor_shift <= 46;
52'b000000000000000000000000000000000000000000000001????: divisor_shift <= 47;
52'b0000000000000000000000000000000000000000000000001???: divisor_shift <= 48;
52'b00000000000000000000000000000000000000000000000001??: divisor_shift <= 49;
52'b000000000000000000000000000000000000000000000000001?: divisor_shift <= 50;
52'b0000000000000000000000000000000000000000000000000001: divisor_shift <= 51;
52'b0000000000000000000000000000000000000000000000000000: divisor_shift <= 52;
endcase
endmodule
/tags/arelease/fpu_sub.v
0,0 → 1,221
/////////////////////////////////////////////////////////////////////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 100ps
 
 
module fpu_sub( clk, rst, enable, opa, opb, fpu_op, sign, diff_2, exponent_2);
input clk;
input rst;
input enable;
input [63:0] opa, opb;
input [2:0] fpu_op;
output sign;
output [55:0] diff_2;
output [10:0] exponent_2;
reg [6:0] diff_shift;
reg [6:0] diff_shift_2;
 
 
reg [10:0] exponent_a;
reg [10:0] exponent_b;
reg [51:0] mantissa_a;
reg [51:0] mantissa_b;
reg expa_gt_expb;
reg expa_et_expb;
reg mana_gtet_manb;
reg a_gtet_b;
reg sign;
reg [10:0] exponent_small;
reg [10:0] exponent_large;
reg [51:0] mantissa_small;
reg [51:0] mantissa_large;
reg small_is_denorm;
reg large_is_denorm;
reg large_norm_small_denorm;
reg small_is_nonzero;
reg [10:0] exponent_diff;
reg [54:0] minuend;
reg [54:0] subtrahend;
reg [54:0] subtra_shift;
wire subtra_shift_nonzero = |subtra_shift[54:0];
wire subtra_fraction_enable = small_is_nonzero & !subtra_shift_nonzero;
wire [54:0] subtra_shift_2 = { 54'b0, 1'b1 };
reg [54:0] subtra_shift_3;
reg [54:0] diff;
reg diffshift_gt_exponent;
reg diffshift_et_55; // when the difference = 0
reg [54:0] diff_1;
reg [10:0] exponent;
reg [10:0] exponent_2;
wire in_norm_out_denorm = (exponent_large > 0) & (exponent== 0);
reg [55:0] diff_2;
 
always @(posedge clk)
begin
if (rst) begin
exponent_a <= 0;
exponent_b <= 0;
mantissa_a <= 0;
mantissa_b <= 0;
expa_gt_expb <= 0;
expa_et_expb <= 0;
mana_gtet_manb <= 0;
a_gtet_b <= 0;
sign <= 0;
exponent_small <= 0;
exponent_large <= 0;
mantissa_small <= 0;
mantissa_large <= 0;
small_is_denorm <= 0;
large_is_denorm <= 0;
large_norm_small_denorm <= 0;
small_is_nonzero <= 0;
exponent_diff <= 0;
minuend <= 0;
subtrahend <= 0;
subtra_shift <= 0;
subtra_shift_3 <= 0;
diff_shift_2 <= 0;
diff <= 0;
diffshift_gt_exponent <= 0;
diffshift_et_55 <= 0;
diff_1 <= 0;
exponent <= 0;
exponent_2 <= 0;
diff_2 <= 0;
end
else if (enable) begin
exponent_a <= opa[62:52];
exponent_b <= opb[62:52];
mantissa_a <= opa[51:0];
mantissa_b <= opb[51:0];
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 ? opa[63] :!opb[63] ^ (fpu_op == 3'b000);
exponent_small <= a_gtet_b ? exponent_b : exponent_a;
exponent_large <= a_gtet_b ? exponent_a : exponent_b;
mantissa_small <= a_gtet_b ? mantissa_b : mantissa_a;
mantissa_large <= a_gtet_b ? mantissa_a : mantissa_b;
small_is_denorm <= !(exponent_small > 0);
large_is_denorm <= !(exponent_large > 0);
large_norm_small_denorm <= (small_is_denorm == 1 && large_is_denorm == 0);
small_is_nonzero <= (exponent_small > 0) | |mantissa_small[51:0];
exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm;
minuend <= { !large_is_denorm, mantissa_large, 2'b00 };
subtrahend <= { !small_is_denorm, mantissa_small, 2'b00 };
subtra_shift <= subtrahend >> exponent_diff;
subtra_shift_3 <= subtra_fraction_enable ? subtra_shift_2 : subtra_shift;
diff_shift_2 <= diff_shift;
diff <= minuend - subtra_shift_3;
diffshift_gt_exponent <= diff_shift_2 > exponent_large;
diffshift_et_55 <= diff_shift_2 == 55;
diff_1 <= diffshift_gt_exponent ? diff << exponent_large : diff << diff_shift_2;
exponent <= diffshift_gt_exponent ? 0 : (exponent_large - diff_shift_2);
exponent_2 <= diffshift_et_55 ? 0 : exponent;
diff_2 <= in_norm_out_denorm ? { 1'b0, diff_1 >> 1} : {1'b0, diff_1};
end
end
 
always @(diff)
casex(diff)
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
 
 
endmodule
/tags/arelease/fpu_mul.v
0,0 → 1,273
/////////////////////////////////////////////////////////////////////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 100ps
 
module fpu_mul( clk, rst, enable, opa, opb, sign, product_7, exponent_5);
input clk;
input rst;
input enable;
input [63:0] opa, opb;
output sign;
output [55:0] product_7;
output [11:0] exponent_5;
 
reg [5:0] product_shift;
reg [5:0] product_shift_2;
 
 
reg sign;
reg [51:0] mantissa_a;
reg [51:0] mantissa_b;
reg [10:0] exponent_a;
reg [10:0] exponent_b;
reg a_is_norm;
reg b_is_norm;
reg a_is_zero;
reg b_is_zero;
reg in_zero;
reg [11:0] exponent_terms;
reg exponent_gt_expoffset;
reg [11:0] exponent_under;
reg [11:0] exponent_1;
wire [11:0] exponent = 0;
reg [11:0] exponent_2;
reg exponent_gt_prodshift;
reg [11:0] exponent_3;
reg [11:0] exponent_4;
reg exponent_et_zero;
reg [52:0] mul_a;
reg [52:0] mul_b;
reg [40:0] product_a;
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 [35:0] sum_1;
reg [41:0] sum_2;
reg [35:0] sum_3;
reg [36:0] sum_4;
reg [27:0] sum_5;
reg [29:0] sum_6;
reg [36:0] sum_7;
reg [30:0] sum_8;
reg [105:0] product;
reg [105:0] product_1;
reg [105:0] product_2;
reg [105:0] product_3;
reg [105:0] product_4;
reg [105:0] product_5;
reg [105:0] product_6;
reg product_lsb; // if there are any 1's in the remainder
wire [55:0] product_7 = { 1'b0, product_6[105:52], product_lsb };
reg [11:0] exponent_5;
 
always @(posedge clk)
begin
if (rst) begin
sign <= 0;
mantissa_a <= 0;
mantissa_b <= 0;
exponent_a <= 0;
exponent_b <= 0;
a_is_norm <= 0;
b_is_norm <= 0;
a_is_zero <= 0;
b_is_zero <= 0;
in_zero <= 0;
exponent_terms <= 0;
exponent_gt_expoffset <= 0;
exponent_under <= 0;
exponent_1 <= 0;
exponent_2 <= 0;
exponent_gt_prodshift <= 0;
exponent_3 <= 0;
exponent_4 <= 0;
exponent_et_zero <= 0;
mul_a <= 0;
mul_b <= 0;
product_a <= 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_1 <= 0;
sum_2 <= 0;
sum_3 <= 0;
sum_4 <= 0;
sum_5 <= 0;
sum_6 <= 0;
sum_7 <= 0;
sum_8 <= 0;
product <= 0;
product_1 <= 0;
product_2 <= 0;
product_3 <= 0;
product_4 <= 0;
product_5 <= 0;
product_6 <= 0;
product_lsb <= 0;
exponent_5 <= 0;
product_shift_2 <= 0;
end
else if (enable) begin
sign <= opa[63] ^ opb[63];
mantissa_a <= opa[51:0];
mantissa_b <= opb[51:0];
exponent_a <= opa[62:52];
exponent_b <= opb[62:52];
a_is_norm <= |exponent_a;
b_is_norm <= |exponent_b;
a_is_zero <= !(|opa[62:0]);
b_is_zero <= !(|opb[62:0]);
in_zero <= a_is_zero | b_is_zero;
exponent_terms <= exponent_a + exponent_b + !a_is_norm + !b_is_norm;
exponent_gt_expoffset <= exponent_terms > 1021;
exponent_under <= 1022 - exponent_terms;
exponent_1 <= exponent_terms - 1022;
exponent_2 <= exponent_gt_expoffset ? exponent_1 : exponent;
exponent_gt_prodshift <= exponent_2 > product_shift_2;
exponent_3 <= exponent_2 - product_shift;
exponent_4 <= exponent_gt_prodshift ? exponent_3 : exponent;
exponent_et_zero <= exponent_4 == 0;
mul_a <= { a_is_norm, mantissa_a };
mul_b <= { b_is_norm, mantissa_b };
product_a <= mul_a[23:0] * mul_b[16:0];
product_b <= mul_a[23:0] * mul_b[33:17];
product_c <= mul_a[23:0] * mul_b[50:34];
product_d <= mul_a[23:0] * mul_b[52:51];
product_e <= mul_a[40:24] * mul_b[16:0];
product_f <= mul_a[40:24] * mul_b[33:17];
product_g <= mul_a[40:24] * mul_b[52:34];
product_h <= mul_a[52:41] * mul_b[16:0];
product_i <= mul_a[52:41] * mul_b[33:17];
product_j <= mul_a[52:41] * mul_b[52:34];
sum_0 <= product_a[40:17] + product_b;
sum_1 <= sum_0[41:7] + product_e;
sum_2 <= sum_1[35:10] + product_c;
sum_3 <= sum_2[41:7] + product_h;
sum_4 <= sum_3 + product_f;
sum_5 <= sum_4[36:10] + product_d;
sum_6 <= sum_5[27:7] + product_i;
sum_7 <= sum_6 + product_g;
sum_8 <= sum_7[36:17] + product_j;
product <= { sum_8, sum_7[16:0], sum_5[6:0], sum_4[9:0], sum_2[6:0],
sum_1[9:0], sum_0[6:0], product_a[16:0] };
product_1 <= product >> exponent_under;
product_2 <= exponent_gt_expoffset ? product : product_1;
product_3 <= product_2 << product_shift_2;
product_4 <= product_2 << exponent_2;
product_5 <= exponent_gt_prodshift ? product_3 : product_4;
product_6 <= exponent_et_zero ? product_5 >> 1 : product_5;
product_lsb <= |product_6[51:0];
exponent_5 <= in_zero ? 12'b0 : exponent_4;
product_shift_2 <= product_shift; // redundant register
// reduces fanout on product_shift
end
end
 
always @(product)
casex(product)
106'b1?????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 0;
106'b01????????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 1;
106'b001???????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 2;
106'b0001??????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 3;
106'b00001?????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 4;
106'b000001????????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 5;
106'b0000001???????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 6;
106'b00000001??????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 7;
106'b000000001?????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 8;
106'b0000000001????????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 9;
106'b00000000001???????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 10;
106'b000000000001??????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 11;
106'b0000000000001?????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 12;
106'b00000000000001????????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 13;
106'b000000000000001???????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 14;
106'b0000000000000001??????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 15;
106'b00000000000000001?????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 16;
106'b000000000000000001????????????????????????????????????????????????????????????????????????????????????????: product_shift <= 17;
106'b0000000000000000001???????????????????????????????????????????????????????????????????????????????????????: product_shift <= 18;
106'b00000000000000000001??????????????????????????????????????????????????????????????????????????????????????: product_shift <= 19;
106'b000000000000000000001?????????????????????????????????????????????????????????????????????????????????????: product_shift <= 20;
106'b0000000000000000000001????????????????????????????????????????????????????????????????????????????????????: product_shift <= 21;
106'b00000000000000000000001???????????????????????????????????????????????????????????????????????????????????: product_shift <= 22;
106'b000000000000000000000001??????????????????????????????????????????????????????????????????????????????????: product_shift <= 23;
106'b0000000000000000000000001?????????????????????????????????????????????????????????????????????????????????: product_shift <= 24;
106'b00000000000000000000000001????????????????????????????????????????????????????????????????????????????????: product_shift <= 25;
106'b000000000000000000000000001???????????????????????????????????????????????????????????????????????????????: product_shift <= 26;
106'b0000000000000000000000000001??????????????????????????????????????????????????????????????????????????????: product_shift <= 27;
106'b00000000000000000000000000001?????????????????????????????????????????????????????????????????????????????: product_shift <= 28;
106'b000000000000000000000000000001????????????????????????????????????????????????????????????????????????????: product_shift <= 29;
106'b0000000000000000000000000000001???????????????????????????????????????????????????????????????????????????: product_shift <= 30;
106'b00000000000000000000000000000001??????????????????????????????????????????????????????????????????????????: product_shift <= 31;
106'b000000000000000000000000000000001?????????????????????????????????????????????????????????????????????????: product_shift <= 32;
106'b0000000000000000000000000000000001????????????????????????????????????????????????????????????????????????: product_shift <= 33;
106'b00000000000000000000000000000000001???????????????????????????????????????????????????????????????????????: product_shift <= 34;
106'b000000000000000000000000000000000001??????????????????????????????????????????????????????????????????????: product_shift <= 35;
106'b0000000000000000000000000000000000001?????????????????????????????????????????????????????????????????????: product_shift <= 36;
106'b00000000000000000000000000000000000001????????????????????????????????????????????????????????????????????: product_shift <= 37;
106'b000000000000000000000000000000000000001???????????????????????????????????????????????????????????????????: product_shift <= 38;
106'b0000000000000000000000000000000000000001??????????????????????????????????????????????????????????????????: product_shift <= 39;
106'b00000000000000000000000000000000000000001?????????????????????????????????????????????????????????????????: product_shift <= 40;
106'b000000000000000000000000000000000000000001????????????????????????????????????????????????????????????????: product_shift <= 41;
106'b0000000000000000000000000000000000000000001???????????????????????????????????????????????????????????????: product_shift <= 42;
106'b00000000000000000000000000000000000000000001??????????????????????????????????????????????????????????????: product_shift <= 43;
106'b000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????????: product_shift <= 44;
106'b0000000000000000000000000000000000000000000001????????????????????????????????????????????????????????????: product_shift <= 45;
106'b00000000000000000000000000000000000000000000001???????????????????????????????????????????????????????????: product_shift <= 46;
106'b000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????????: product_shift <= 47;
106'b0000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????????: product_shift <= 48;
106'b00000000000000000000000000000000000000000000000001????????????????????????????????????????????????????????: product_shift <= 49;
106'b000000000000000000000000000000000000000000000000001???????????????????????????????????????????????????????: product_shift <= 50;
106'b0000000000000000000000000000000000000000000000000001??????????????????????????????????????????????????????: product_shift <= 51;
106'b00000000000000000000000000000000000000000000000000001?????????????????????????????????????????????????????: product_shift <= 52;
106'b000000000000000000000000000000000000000000000000000000????????????????????????????????????????????????????: product_shift <= 53;
// It's not necessary to go past 53, because you will only get more than 53 zeros
// when multiplying 2 denormalized numbers together, in which case you will underflow
endcase
 
endmodule
/tags/arelease/pipeline/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%)
/tags/arelease/pipeline/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
/tags/arelease/pipeline/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
/tags/arelease/pipeline/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
/tags/arelease/pipeline/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
/tags/arelease/Double_FPU.PDF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/arelease/Double_FPU.PDF Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/arelease/fpu_exceptions.v =================================================================== --- tags/arelease/fpu_exceptions.v (nonexistent) +++ tags/arelease/fpu_exceptions.v (revision 12) @@ -0,0 +1,280 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + +module fpu_exceptions( clk, rst, enable, rmode, opa, opb, in_except, +exponent_in, mantissa_in, fpu_op, out, ex_enable, underflow, overflow, +inexact, exception, invalid); +input clk; +input rst; +input enable; +input [1:0] rmode; +input [63:0] opa; +input [63:0] opb; +input [63:0] in_except; +input [11:0] exponent_in; +input [1:0] mantissa_in; +input [2:0] fpu_op; +output [63:0] out; +output ex_enable; +output underflow; +output overflow; +output inexact; +output exception; +output invalid; + +reg [63:0] out; +reg ex_enable; +reg underflow; +reg overflow; +reg inexact; +reg exception; +reg invalid; + +reg in_et_zero; +reg opa_et_zero; +reg opb_et_zero; +reg input_et_zero; +reg add; +reg subtract; +reg multiply; +reg divide; +reg opa_QNaN; +reg opb_QNaN; +reg opa_SNaN; +reg opb_SNaN; +reg opa_pos_inf; +reg opb_pos_inf; +reg opa_neg_inf; +reg opb_neg_inf; +reg opa_inf; +reg opb_inf; +reg NaN_input; +reg SNaN_input; +reg a_NaN; +reg div_by_0; +reg div_0_by_0; +reg div_inf_by_inf; +reg div_by_inf; +reg mul_0_by_inf; +reg mul_inf; +reg div_inf; +reg add_inf; +reg sub_inf; +reg addsub_inf_invalid; +reg addsub_inf; +reg out_inf_trigger; +reg out_pos_inf; +reg out_neg_inf; +reg round_nearest; +reg round_to_zero; +reg round_to_pos_inf; +reg round_to_neg_inf; +reg inf_round_down_trigger; +reg mul_uf; +reg div_uf; +reg underflow_trigger; +reg invalid_trigger; +reg overflow_trigger; +reg inexact_trigger; +reg except_trigger; +reg enable_trigger; +reg NaN_out_trigger; +reg SNaN_trigger; + + +wire [10:0] exp_2047 = 11'b11111111111; +wire [10:0] exp_2046 = 11'b11111111110; +reg [62:0] NaN_output_0; +reg [62:0] NaN_output; +wire [51:0] mantissa_max = 52'b1111111111111111111111111111111111111111111111111111; +reg [62:0] inf_round_down; +reg [62:0] out_inf; +reg [63:0] out_0; +reg [63:0] out_1; +reg [63:0] out_2; + +always @(posedge clk) +begin + if (rst) begin + in_et_zero <= 0; + opa_et_zero <= 0; + opb_et_zero <= 0; + input_et_zero <= 0; + add <= 0; + subtract <= 0; + multiply <= 0; + divide <= 0; + opa_QNaN <= 0; + opb_QNaN <= 0; + opa_SNaN <= 0; + opb_SNaN <= 0; + opa_pos_inf <= 0; + opb_pos_inf <= 0; + opa_neg_inf <= 0; + opb_neg_inf <= 0; + opa_inf <= 0; + opb_inf <= 0; + NaN_input <= 0; + SNaN_input <= 0; + a_NaN <= 0; + div_by_0 <= 0; + div_0_by_0 <= 0; + div_inf_by_inf <= 0; + div_by_inf <= 0; + mul_0_by_inf <= 0; + mul_inf <= 0; + div_inf <= 0; + add_inf <= 0; + sub_inf <= 0; + addsub_inf_invalid <= 0; + addsub_inf <= 0; + out_inf_trigger <= 0; + out_pos_inf <= 0; + out_neg_inf <= 0; + round_nearest <= 0; + round_to_zero <= 0; + round_to_pos_inf <= 0; + round_to_neg_inf <= 0; + inf_round_down_trigger <= 0; + mul_uf <= 0; + div_uf <= 0; + underflow_trigger <= 0; + invalid_trigger <= 0; + overflow_trigger <= 0; + inexact_trigger <= 0; + except_trigger <= 0; + enable_trigger <= 0; + NaN_out_trigger <= 0; + SNaN_trigger <= 0; + NaN_output_0 <= 0; + NaN_output <= 0; + inf_round_down <= 0; + out_inf <= 0; + out_0 <= 0; + out_1 <= 0; + out_2 <= 0; + end + else if (enable) begin + in_et_zero <= !(|in_except[62:0]); + opa_et_zero <= !(|opa[62:0]); + opb_et_zero <= !(|opb[62:0]); + input_et_zero <= !(|in_except[62:0]); + add <= fpu_op == 3'b000; + subtract <= fpu_op == 3'b001; + multiply <= fpu_op == 3'b010; + divide <= fpu_op == 3'b011; + opa_QNaN <= (opa[62:52] == 2047) & |opa[51:0] & opa[51]; + opb_QNaN <= (opb[62:52] == 2047) & |opb[51:0] & opb[51]; + opa_SNaN <= (opa[62:52] == 2047) & |opa[51:0] & !opa[51]; + opb_SNaN <= (opb[62:52] == 2047) & |opb[51:0] & !opb[51]; + opa_pos_inf <= !opa[63] & (opa[62:52] == 2047) & !(|opa[51:0]); + opb_pos_inf <= !opb[63] & (opb[62:52] == 2047) & !(|opb[51:0]); + opa_neg_inf <= opa[63] & (opa[62:52] == 2047) & !(|opa[51:0]); + opb_neg_inf <= opb[63] & (opb[62:52] == 2047) & !(|opb[51:0]); + opa_inf <= (opa[62:52] == 2047) & !(|opa[51:0]); + opb_inf <= (opb[62:52] == 2047) & !(|opb[51:0]); + NaN_input <= opa_QNaN | opb_QNaN | opa_SNaN | opb_SNaN; + SNaN_input <= opa_SNaN | opb_SNaN; + a_NaN <= opa_QNaN | opa_SNaN; + div_by_0 <= divide & opb_et_zero & !opa_et_zero; + div_0_by_0 <= divide & opb_et_zero & opa_et_zero; + div_inf_by_inf <= divide & opa_inf & opb_inf; + div_by_inf <= divide & !opa_inf & opb_inf; + mul_0_by_inf <= multiply & ((opa_inf & opb_et_zero) | (opa_et_zero & opb_inf)); + mul_inf <= multiply & (opa_inf | opb_inf) & !mul_0_by_inf; + div_inf <= divide & opa_inf & !opb_inf; + add_inf <= (add & (opa_inf | opb_inf)); + sub_inf <= (subtract & (opa_inf | opb_inf)); + addsub_inf_invalid <= (add & opa_pos_inf & opb_neg_inf) | (add & opa_neg_inf & opb_pos_inf) | + (subtract & opa_pos_inf & opb_pos_inf) | (subtract & opa_neg_inf & opb_neg_inf); + addsub_inf <= (add_inf | sub_inf) & !addsub_inf_invalid; + out_inf_trigger <= addsub_inf | mul_inf | div_inf | div_by_0 | (exponent_in > 2046); + out_pos_inf <= out_inf_trigger & !in_except[63]; + out_neg_inf <= out_inf_trigger & in_except[63]; + round_nearest <= (rmode == 2'b00); + round_to_zero <= (rmode == 2'b01); + round_to_pos_inf <= (rmode == 2'b10); + round_to_neg_inf <= (rmode == 2'b11); + inf_round_down_trigger <= (out_pos_inf & round_to_neg_inf) | + (out_neg_inf & round_to_pos_inf) | + (out_inf_trigger & round_to_zero); + mul_uf <= multiply & !opa_et_zero & !opb_et_zero & in_et_zero; + div_uf <= divide & !opa_et_zero & in_et_zero; + underflow_trigger <= div_by_inf | mul_uf | div_uf; + invalid_trigger <= SNaN_input | addsub_inf_invalid | mul_0_by_inf | + div_0_by_0 | div_inf_by_inf; + overflow_trigger <= out_inf_trigger & !NaN_input; + inexact_trigger <= (|mantissa_in[1:0] | out_inf_trigger | underflow_trigger) & + !NaN_input; + except_trigger <= invalid_trigger | overflow_trigger | underflow_trigger | + inexact_trigger; + enable_trigger <= except_trigger | out_inf_trigger | NaN_input; + NaN_out_trigger <= NaN_input | invalid_trigger; + SNaN_trigger <= invalid_trigger & !SNaN_input; + NaN_output_0 <= a_NaN ? { exp_2047, 1'b1, opa[50:0]} : { exp_2047, 1'b1, opb[50:0]}; + NaN_output <= SNaN_trigger ? { exp_2047, 2'b01, opa[49:0]} : NaN_output_0; + inf_round_down <= { exp_2046, mantissa_max }; + out_inf <= inf_round_down_trigger ? inf_round_down : { exp_2047, 52'b0 }; + out_0 <= underflow_trigger ? { in_except[63], 63'b0 } : in_except; + out_1 <= out_inf_trigger ? { in_except[63], out_inf } : out_0; + out_2 <= NaN_out_trigger ? { in_except[63], NaN_output} : out_1; + end +end + +always @(posedge clk) +begin + if (rst) begin + ex_enable <= 0; + underflow <= 0; + overflow <= 0; + inexact <= 0; + exception <= 0; + invalid <= 0; + out <= 0; + end + else if (enable) begin + ex_enable <= enable_trigger; + underflow <= underflow_trigger; + overflow <= overflow_trigger; + inexact <= inexact_trigger; + exception <= except_trigger; + invalid <= invalid_trigger; + out <= out_2; + end +end + +endmodule Index: tags/arelease/fpu_TB.v =================================================================== --- tags/arelease/fpu_TB.v (nonexistent) +++ tags/arelease/fpu_TB.v (revision 12) @@ -0,0 +1,845 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ps / 1ps + +module fpu_tb; + +reg clk; +reg rst; +reg enable; +reg [1:0]rmode; +reg [2:0]fpu_op; +reg [63:0]opa; +reg [63:0]opb; +wire [63:0]out; +wire ready; +wire underflow; +wire overflow; +wire inexact; +wire exception; +wire invalid; + +reg [6:0] count; + + + fpu UUT ( + .clk(clk), + .rst(rst), + .enable(enable), + .rmode(rmode), + .fpu_op(fpu_op), + .opa(opa), + .opb(opb), + .out(out), + .ready(ready), + .underflow(underflow), + .overflow(overflow), + .inexact(inexact), + .exception(exception), + .invalid(invalid)); + + +initial +begin : STIMUL + #0 + count = 0; + rst = 1'b1; + #20000; + rst = 1'b0; // paste after this +//inputA:1.6999999999e-314 +//inputB:4.0000000000e-300 +enable = 1'b1; +opa = 64'b0000000000000000000000000000000011001101000101110000011010100010; +opb = 64'b0000000111000101011011100001111111000010111110001111001101011001; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:4.249999999722977e-015 +if (out==64'h3CF323EA98D06FB6) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.0000000000e-290 +//inputB:3.0000000000e-021 +enable = 1'b1; +opa = 64'b0000001111010010101101100000010001001001010000101111100001010101; +opb = 64'b0011101110101100010101011000111000001111000101011110100011110111; +fpu_op = 3'b010; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:9.000000000000022e-311 +if (out==64'h000010914A4C025A) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.6500000000e+002 +//inputB:6.5000000000e+001 +enable = 1'b1; +opa = 64'b0100000001111101000100000000000000000000000000000000000000000000; +opb = 64'b0100000001010000010000000000000000000000000000000000000000000000; +fpu_op = 3'b001; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:4.000000000000000e+002 +if (out==64'h4079000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.2700000000e-001 +//inputB:3.4000000000e+001 +enable = 1'b1; +opa = 64'b0011111111001101000011100101011000000100000110001001001101110101; +opb = 64'b0100000001000001000000000000000000000000000000000000000000000000; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:3.422700000000000e+001 +if (out==64'h40411D0E56041894) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.2300000000e+002 +//inputB:5.6000000000e+001 +enable = 1'b1; +opa = 64'b0100000001101011111000000000000000000000000000000000000000000000; +opb = 64'b0100000001001100000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:3.982142857142857e+000 +if (out==64'h400FDB6DB6DB6DB7) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-9.5000000000e+001 +//inputB:2.0000000000e+002 +enable = 1'b1; +opa = 64'b1100000001010111110000000000000000000000000000000000000000000000; +opb = 64'b0100000001101001000000000000000000000000000000000000000000000000; +fpu_op = 3'b010; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:-1.900000000000000e+004 +if (out==64'hC0D28E0000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.5000000000e+001 +//inputB:-3.2000000000e+001 +enable = 1'b1; +opa = 64'b1100000001000110100000000000000000000000000000000000000000000000; +opb = 64'b1100000001000000000000000000000000000000000000000000000000000000; +fpu_op = 3'b001; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:-1.300000000000000e+001 +if (out==64'hC02A000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-9.0300000000e+002 +//inputB:2.1000000000e+001 +enable = 1'b1; +opa = 64'b1100000010001100001110000000000000000000000000000000000000000000; +opb = 64'b0100000000110101000000000000000000000000000000000000000000000000; +fpu_op = 3'b000; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:-8.820000000000000e+002 +if (out==64'hC08B900000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.5500000000e+002 +//inputB:-4.5900000000e+002 +enable = 1'b1; +opa = 64'b0100000001111100011100000000000000000000000000000000000000000000; +opb = 64'b1100000001111100101100000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:-9.912854030501089e-001 +if (out==64'hBFEFB89C2A6346D5) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.3577000000e+002 +//inputB:2.0000000000e-002 +enable = 1'b1; +opa = 64'b0100000001101101011110001010001111010111000010100011110101110001; +opb = 64'b0011111110010100011110101110000101000111101011100001010001111011; +fpu_op = 3'b010; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.715400000000001e+000 +if (out==64'h4012DC91D14E3BCE) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.0195000000e+002 +//inputB:-3.3600000000e+001 +enable = 1'b1; +opa = 64'b0100000001111001000111110011001100110011001100110011001100110011; +opb = 64'b1100000001000000110011001100110011001100110011001100110011001101; +fpu_op = 3'b001; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:4.355500000000000e+002 +if (out==64'h407B38CCCCCCCCCC) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-1.0000000000e-309 +//inputB:1.1000000000e-309 +enable = 1'b1; +opa = 64'b1000000000000000101110000001010101110010011010001111110110101110; +opb = 64'b0000000000000000110010100111110111111101110110011110001111011001; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:9.999999999999969e-311 +if (out==64'h000012688B70E62B) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.0000000000e-200 +//inputB:2.0000000000e+002 +enable = 1'b1; +opa = 64'b0001011010001000011111101001001000010101010011101111011110101100; +opb = 64'b0100000001101001000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:2.000000000000000e-202 +if (out==64'h160F5A549627A36C) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.0000000000e+020 +//inputB:2.0000000000e+002 +enable = 1'b1; +opa = 64'b0100010000110101101011110001110101111000101101011000110001000000; +opb = 64'b0100000001101001000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:2.000000000000000e+018 +if (out==64'h43BBC16D674EC800) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:5.0000000000e+000 +//inputB:2.5000000000e+000 +enable = 1'b1; +opa = 64'b0100000000010100000000000000000000000000000000000000000000000000; +opb = 64'b0100000000000100000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:2.000000000000000e+000 +if (out==64'h4000000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:1.0000000000e-312 +//inputB:1.0000000000e+000 +enable = 1'b1; +opa = 64'b0000000000000000000000000010111100100000000111010100100111111011; +opb = 64'b0011111111110000000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:9.999999999984653e-313 +if (out==64'h0000002F201D49FB) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.8999000000e+004 +//inputB:2.3600000000e+001 +enable = 1'b1; +opa = 64'b0100000011100111111011001110000000000000000000000000000000000000; +opb = 64'b0100000000110111100110011001100110011001100110011001100110011010; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.897540000000000e+004 +if (out==64'h40E7E9ECCCCCCCCD) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.0000000000e-200 +//inputB:3.0000000000e+111 +enable = 1'b1; +opa = 64'b0001011010001000011111101001001000010101010011101111011110101100; +opb = 64'b0101011100010011111101011000110101000011010010100010101110101110; +fpu_op = 3'b011; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:1.333333333333758e-311 +if (out==64'h0000027456DBDA6D) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:7.0000000000e-310 +//inputB:8.0000000000e-100 +enable = 1'b1; +opa = 64'b0000000000000000100000001101101111010000000101100100101100101101; +opb = 64'b0010101101011011111111110010111011100100100011100000010100110000; +fpu_op = 3'b011; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:8.749999999999972e-211 +if (out==64'h14526914EEBBD470) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:1.4000000000e-311 +//inputB:2.5000000000e-310 +enable = 1'b1; +opa = 64'b0000000000000000000000101001001111000001100110100000101110111110; +opb = 64'b0000000000000000001011100000010101011100100110100011111101101011; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:5.599999999999383e-002 +if (out==64'h3FACAC083126E600) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.0600000000e+001 +//inputB:-3.5700000000e+001 +enable = 1'b1; +opa = 64'b1100000001000100010011001100110011001100110011001100110011001101; +opb = 64'b1100000001000001110110011001100110011001100110011001100110011010; +fpu_op = 3'b000; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:-7.630000000000001e+001 +if (out==64'hC053133333333334) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.4500000000e+002 +//inputB:-3.4400000000e+002 +enable = 1'b1; +opa = 64'b0100000001110101100100000000000000000000000000000000000000000000; +opb = 64'b1100000001110101100000000000000000000000000000000000000000000000; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:1.000000000000000e+000 +if (out==64'h3FF0000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.3770000000e+001 +//inputB:-4.5000000000e+001 +enable = 1'b1; +opa = 64'b0100000000110111110001010001111010111000010100011110101110000101; +opb = 64'b1100000001000110100000000000000000000000000000000000000000000000; +fpu_op = 3'b001; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:6.877000000000000e+001 +if (out==64'h40513147AE147AE1) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.7700000000e+002 +//inputB:4.8960000000e+002 +enable = 1'b1; +opa = 64'b1100000001111101110100000000000000000000000000000000000000000000; +opb = 64'b0100000001111110100110011001100110011001100110011001100110011010; +fpu_op = 3'b010; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:-2.335392000000000e+005 +if (out==64'hC10C82199999999A) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.0000000000e-311 +//inputB:0.0000000000e+000 +enable = 1'b1; +opa = 64'b0000000000000000000000111010111010000010010010011100011110100010; +opb = 64'b0000000000000000000000000000000000000000000000000000000000000000; +fpu_op = 3'b000; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:1.999999999999895e-311 +if (out==64'h000003AE8249C7A2) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:0.0000000000e+000 +//inputB:9.0000000000e+050 +enable = 1'b1; +opa = 64'b0000000000000000000000000000000000000000000000000000000000000000; +opb = 64'b0100101010000011001111100111000010011110001011100011000100101101; +fpu_op = 3'b010; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:0.000000000000000e+000 +if (out==64'h0000000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:5.4000000000e+001 +//inputB:0.0000000000e+000 +enable = 1'b1; +opa = 64'b0100000001001011000000000000000000000000000000000000000000000000; +opb = 64'b0000000000000000000000000000000000000000000000000000000000000000; +fpu_op = 3'b000; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:5.400000000000000e+001 +if (out==64'h404B000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-6.7000000000e+001 +//inputB:0.0000000000e+000 +enable = 1'b1; +opa = 64'b1100000001010000110000000000000000000000000000000000000000000000; +opb = 64'b0000000000000000000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:-1.#INF00000000000e+000 +if (out==64'hFFEFFFFFFFFFFFFF) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.5600000000e+001 +//inputB:-6.9000000000e+001 +enable = 1'b1; +opa = 64'b1100000001000110110011001100110011001100110011001100110011001101; +opb = 64'b1100000001010001010000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:6.608695652173914e-001 +if (out==64'h3FE525D7EE30F953) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-5.9900000000e+002 +//inputB:2.7000000000e-002 +enable = 1'b1; +opa = 64'b1100000010000010101110000000000000000000000000000000000000000000; +opb = 64'b0011111110011011101001011110001101010011111101111100111011011001; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:-2.218518518518519e+004 +if (out==64'hC0D5AA4BDA12F685) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.1000000000e-308 +//inputB:2.0000000000e-308 +enable = 1'b1; +opa = 64'b0000000000001111000110011100001001100010100111001100111101010011; +opb = 64'b0000000000001110011000011010110011110000001100111101000110100100; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.100000000000000e-308 +if (out==64'h001D7B6F52D0A0F7) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:5.0000000000e-308 +//inputB:2.0000000000e-312 +enable = 1'b1; +opa = 64'b0000000000100001111110100001100000101100010000001100011000001101; +opb = 64'b0000000000000000000000000101111001000000001110101001001111110110; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:5.000199999999999e-308 +if (out==64'h0021FA474C5E1008) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.9800000000e+000 +//inputB:3.7700000000e+000 +enable = 1'b1; +opa = 64'b0100000000001111110101110000101000111101011100001010001111010111; +opb = 64'b0100000000001110001010001111010111000010100011110101110000101001; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:7.750000000000000e+000 +if (out==64'h401F000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.4000000000e+001 +//inputB:7.9000000000e-002 +enable = 1'b1; +opa = 64'b0100000001000110000000000000000000000000000000000000000000000000; +opb = 64'b0011111110110100001110010101100000010000011000100100110111010011; +fpu_op = 3'b000; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:4.407900000000000e+001 +if (out==64'h40460A1CAC083127) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:5.0000000000e-311 +//inputB:9.0000000000e+009 +enable = 1'b1; +opa = 64'b0000000000000000000010010011010001000101101110000111001100010101; +opb = 64'b0100001000000000110000111000100011010000000000000000000000000000; +fpu_op = 3'b010; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.499999999999764e-301 +if (out==64'h01934982FC467380) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.0000000000e-305 +//inputB:2.0000000000e-008 +enable = 1'b1; +opa = 64'b1000000010111100000101101100010111000101001001010011010101110101; +opb = 64'b0011111001010101011110011000111011100010001100001000110000111010; +fpu_op = 3'b010; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:-8.000000000007485e-313 +if (out==64'h80000025B34AA196) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.0000000000e-308 +//inputB:1.0000000000e-012 +enable = 1'b1; +opa = 64'b0000000000010101100100101000001101101000010011011011101001110111; +opb = 64'b0011110101110001100101111001100110000001001011011110101000010001; +fpu_op = 3'b010; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:2.999966601548049e-320 +if (out==64'h00000000000017B8) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:5.6999990000e+006 +//inputB:5.6999989900e+006 +enable = 1'b1; +opa = 64'b0100000101010101101111100110011111000000000000000000000000000000; +opb = 64'b0100000101010101101111100110011110111111010111000010100011110110; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:9.999999776482582e-003 +if (out==64'h3F847AE140000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-4.0000000000e+000 +//inputB:9.0000000000e+000 +enable = 1'b1; +opa = 64'b1100000000010000000000000000000000000000000000000000000000000000; +opb = 64'b0100000000100010000000000000000000000000000000000000000000000000; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:-1.300000000000000e+001 +if (out==64'hC02A000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.9700000000e+001 +//inputB:2.5700000000e-002 +enable = 1'b1; +opa = 64'b0100000001000011110110011001100110011001100110011001100110011010; +opb = 64'b0011111110011010010100010001100111001110000001110101111101110000; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:3.967430000000001e+001 +if (out==64'h4043D64F765FD8AF) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:2.3000000000e+000 +//inputB:7.0000000000e-002 +enable = 1'b1; +opa = 64'b0100000000000010011001100110011001100110011001100110011001100110; +opb = 64'b0011111110110001111010111000010100011110101110000101000111101100; +fpu_op = 3'b001; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:2.230000000000000e+000 +if (out==64'h4001D70A3D70A3D7) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:1.9999999673e-316 +//inputB:1.9999999673e-317 +enable = 1'b1; +opa = 64'b0000000000000000000000000000000000000010011010011010111011000010; +opb = 64'b0000000000000000000000000000000000000000001111011100010010101101; +fpu_op = 3'b001; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:1.799999970587486e-316 +if (out==64'h00000000022BEA15) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:1.9999999970e-315 +//inputB:-1.9999999673e-316 +enable = 1'b1; +opa = 64'b0000000000000000000000000000000000011000001000001101001110011010; +opb = 64'b1000000000000000000000000000000000000010011010011010111011000010; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:2.199999993695311e-315 +if (out==64'h000000001A8A825C) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:4.0000000000e+000 +//inputB:1.0000000000e-025 +enable = 1'b1; +opa = 64'b0100000000010000000000000000000000000000000000000000000000000000; +opb = 64'b0011101010111110111100101101000011110101110110100111110111011001; +fpu_op = 3'b001; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.000000000000000e+000 +if (out==64'h4010000000000000) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.0000000000e-310 +//inputB:4.0000000000e-304 +enable = 1'b1; +opa = 64'b0000000000000000001101110011100110100010010100101011001010000001; +opb = 64'b0000000011110001100011100011101110011011001101110100000101101001; +fpu_op = 3'b000; +rmode = 2'b10; +#20000; +enable = 1'b0; +#800000; +//Output:4.000003000000000e-304 +if (out==64'h00F18E3C781DCAB4) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:3.5000000000e-313 +//inputB:7.0000000000e+004 +enable = 1'b1; +opa = 64'b0000000000000000000000000001000001111110011100001010011010110001; +opb = 64'b0100000011110001000101110000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:4.999998683134458e-318 +if (out==64'h00000000000F712B) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-5.1000000000e-306 +//inputB:2.0480000000e+003 +enable = 1'b1; +opa = 64'b1000000010001100101001101001011010000110100001110011101110100101; +opb = 64'b0100000010100000000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:-2.490234375000003e-309 +if (out==64'h8001CA69686873BB) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-1.5000000000e-305 +//inputB:1.0240000000e+003 +enable = 1'b1; +opa = 64'b1000000010100101000100010001010001010011110110111110100000011000; +opb = 64'b0100000010010000000000000000000000000000000000000000000000000000; +fpu_op = 3'b011; +rmode = 2'b11; +#20000; +enable = 1'b0; +#800000; +//Output:-1.464843750000000e-308 +if (out==64'h800A888A29EDF40C) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:-3.4000000000e+056 +//inputB:-4.0000000000e+199 +enable = 1'b1; +opa = 64'b1100101110101011101110111000100000000000101110111001110000000101; +opb = 64'b1110100101100000101110001110000010101100101011000100111010101111; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:8.500000000000000e-144 +if (out==64'h223A88ECC2AC8317) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); +//inputA:1.3559000000e-001 +//inputB:2.3111240000e+003 +enable = 1'b1; +opa = 64'b0011111111000001010110110000001101011011110101010001001011101100; +opb = 64'b0100000010100010000011100011111101111100111011011001000101101000; +fpu_op = 3'b011; +rmode = 2'b00; +#20000; +enable = 1'b0; +#800000; +//Output:5.866842281071894e-005 +if (out==64'h3F0EC257A882625F) + $display($time,"ps Answer is correct %h", out); +else + $display($time,"ps Error! out is incorrect %h", out); + +// end of paste +$finish; +end + +always +begin : CLOCK_clk + + clk = 1'b0; + #5000; + clk = 1'b1; + #5000; +end + +endmodule Index: tags/arelease/fpu_round.v =================================================================== --- tags/arelease/fpu_round.v (nonexistent) +++ tags/arelease/fpu_round.v (revision 12) @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + +module fpu_round( clk, rst, enable, round_mode, sign_term, +mantissa_term, exponent_term, round_out, exponent_final); +input clk; +input rst; +input enable; +input [1:0] round_mode; +input sign_term; +input [55:0] mantissa_term; +input [11:0] exponent_term; +output [63:0] round_out; +output [11:0] exponent_final; + +wire [55:0] rounding_amount = { 53'b0, 1'b1, 2'b0}; +wire round_nearest = (round_mode == 2'b00); +wire round_to_zero = (round_mode == 2'b01); +wire round_to_pos_inf = (round_mode == 2'b10); +wire round_to_neg_inf = (round_mode == 2'b11); +wire round_nearest_trigger = round_nearest & mantissa_term[1]; +wire round_to_pos_inf_trigger = !sign_term & |mantissa_term[1:0]; +wire round_to_neg_inf_trigger = sign_term & |mantissa_term[1:0]; +wire round_trigger = ( round_nearest & round_nearest_trigger) + | (round_to_pos_inf & round_to_pos_inf_trigger) + | (round_to_neg_inf & round_to_neg_inf_trigger); + + +reg [55:0] sum_round; +wire sum_round_overflow = sum_round[55]; + // will be 0 if no carry, 1 if overflow from the rounding unit + // overflow from rounding is extremely rare, but possible +reg [55:0] sum_round_2; +reg [11:0] exponent_round; +reg [55:0] sum_final; +reg [11:0] exponent_final; +reg [63:0] round_out; + +always @(posedge clk) + begin + if (rst) begin + sum_round <= 0; + sum_round_2 <= 0; + exponent_round <= 0; + sum_final <= 0; + exponent_final <= 0; + round_out <= 0; + end + else begin + sum_round <= rounding_amount + mantissa_term; + sum_round_2 <= sum_round_overflow ? sum_round >> 1 : sum_round; + exponent_round <= sum_round_overflow ? (exponent_term + 1) : exponent_term; + sum_final <= round_trigger ? sum_round_2 : mantissa_term; + exponent_final <= round_trigger ? exponent_round : exponent_term; + round_out <= { sign_term, exponent_final[10:0], sum_final[53:2] }; + end + end +endmodule \ No newline at end of file Index: tags/arelease/fpu_add.v =================================================================== --- tags/arelease/fpu_add.v (nonexistent) +++ tags/arelease/fpu_add.v (revision 12) @@ -0,0 +1,130 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + +module fpu_add( clk, rst, enable, opa, opb, sign, sum_2, exponent_2); +input clk; +input rst; +input enable; +input [63:0] opa, opb; +output sign; +output [55:0] sum_2; +output [10:0] exponent_2; + +reg sign; +reg [10:0] exponent_a; +reg [10:0] exponent_b; +reg [51:0] mantissa_a; +reg [51:0] mantissa_b; +reg expa_gt_expb; +reg [10:0] exponent_small; +reg [10:0] exponent_large; +reg [51:0] mantissa_small; +reg [51:0] mantissa_large; +reg small_is_denorm; +reg large_is_denorm; +reg large_norm_small_denorm; +reg [10:0] exponent_diff; +reg [55:0] large_add; +reg [55:0] small_add; +reg [55:0] small_shift; +wire small_shift_nonzero = |small_shift[55:0]; +wire small_is_nonzero = (exponent_small > 0) | |mantissa_small[51:0]; +wire small_fraction_enable = small_is_nonzero & !small_shift_nonzero; +wire [55:0] small_shift_2 = { 55'b0, 1'b1 }; +reg [55:0] small_shift_3; +reg [55:0] sum; +wire sum_overflow = sum[55]; // sum[55] will be 0 if there was no carry from adding the 2 numbers +reg [55:0] sum_2; +reg [10:0] exponent; +wire sum_leading_one = sum_2[54]; // this is where the leading one resides, unless denorm +reg denorm_to_norm; +reg [10:0] exponent_2; + +always @(posedge clk) + begin + if (rst) begin + sign <= 0; + exponent_a <= 0; + exponent_b <= 0; + mantissa_a <= 0; + mantissa_b <= 0; + expa_gt_expb <= 0; + exponent_small <= 0; + exponent_large <= 0; + mantissa_small <= 0; + mantissa_large <= 0; + small_is_denorm <= 0; + large_is_denorm <= 0; + large_norm_small_denorm <= 0; + exponent_diff <= 0; + large_add <= 0; + small_add <= 0; + small_shift <= 0; + small_shift_3 <= 0; + sum <= 0; + sum_2 <= 0; + exponent <= 0; + denorm_to_norm <= 0; + exponent_2 <= 0; + end + else if (enable) begin + sign <= opa[63]; + exponent_a <= opa[62:52]; + exponent_b <= opb[62:52]; + mantissa_a <= opa[51:0]; + mantissa_b <= opb[51:0]; + expa_gt_expb <= exponent_a > exponent_b; + exponent_small <= expa_gt_expb ? exponent_b : exponent_a; + exponent_large <= expa_gt_expb ? exponent_a : exponent_b; + mantissa_small <= expa_gt_expb ? mantissa_b : mantissa_a; + mantissa_large <= expa_gt_expb ? mantissa_a : mantissa_b; + small_is_denorm <= !(exponent_small > 0); + large_is_denorm <= !(exponent_large > 0); + large_norm_small_denorm <= (small_is_denorm && !large_is_denorm); + exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm; + large_add <= { 1'b0, !large_is_denorm, mantissa_large, 2'b0 }; + small_add <= { 1'b0, !small_is_denorm, mantissa_small, 2'b0 }; + small_shift <= small_add >> exponent_diff; + small_shift_3 <= small_fraction_enable ? small_shift_2 : small_shift; + sum <= large_add + small_shift_3; + sum_2 <= sum_overflow ? sum >> 1 : sum; + exponent <= sum_overflow ? exponent_large + 1: exponent_large; + denorm_to_norm <= sum_leading_one & large_is_denorm; + exponent_2 <= denorm_to_norm ? exponent + 1 : exponent; + end + end + +endmodule Index: tags/arelease/fpu_double.v =================================================================== --- tags/arelease/fpu_double.v (nonexistent) +++ tags/arelease/fpu_double.v (revision 12) @@ -0,0 +1,302 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps +/* FPU Operations (fpu_op): +======================== +0 = add +1 = sub +2 = mul +3 = div + +Rounding Modes (rmode): +======================= +0 = round_nearest_even +1 = round_to_zero +2 = round_up +3 = round_down */ + +module fpu( clk, rst, enable, rmode, fpu_op, opa, opb, out, ready, underflow, +overflow, inexact, exception, invalid); +input clk; +input rst; +input enable; +input [1:0] rmode; +input [2:0] fpu_op; +input [63:0] opa, opb; +output [63:0] out; +output ready; +output underflow; +output overflow; +output inexact; +output exception; +output invalid; + +reg [63:0] opa_reg; +reg [63:0] opb_reg; +reg [2:0] fpu_op_reg; +reg [1:0] rmode_reg; +reg enable_reg; +reg enable_reg_1; // high for one clock cycle +reg enable_reg_2; // high for one clock cycle +reg enable_reg_3; // high for two clock cycles +reg op_enable; +reg [63:0] out; +reg [6:0] count_cycles; +reg [6:0] count_ready; +wire count_busy = (count_ready <= count_cycles); +reg ready; +reg ready_0; +reg ready_1; +reg underflow; +reg overflow; +reg inexact; +reg exception; +reg invalid; +wire underflow_0; +wire overflow_0; +wire inexact_0; +wire exception_0; +wire invalid_0; + +wire add_enable_0 = (fpu_op_reg == 3'b000) & !(opa_reg[63] ^ opb_reg[63]); +wire add_enable_1 = (fpu_op_reg == 3'b001) & (opa_reg[63] ^ opb_reg[63]); +reg add_enable; +wire sub_enable_0 = (fpu_op_reg == 3'b000) & (opa_reg[63] ^ opb_reg[63]); +wire sub_enable_1 = (fpu_op_reg == 3'b001) & !(opa_reg[63] ^ opb_reg[63]); +reg sub_enable; +reg mul_enable; +reg div_enable; +wire [55:0] sum_out; +wire [55:0] diff_out; +reg [55:0] addsub_out; +wire [55:0] mul_out; +wire [55:0] div_out; +reg [55:0] mantissa_round; +wire [10:0] exp_add_out; +wire [10:0] exp_sub_out; +wire [11:0] exp_mul_out; +wire [11:0] exp_div_out; +reg [11:0] exponent_round; +reg [11:0] exp_addsub; +wire [11:0] exponent_post_round; +wire add_sign; +wire sub_sign; +wire mul_sign; +wire div_sign; +reg addsub_sign; +reg sign_round; +wire [63:0] out_round; +wire [63:0] out_except; + +fpu_add u1( + .clk(clk),.rst(rst),.enable(add_enable),.opa(opa_reg),.opb(opb_reg), + .sign(add_sign),.sum_2(sum_out),.exponent_2(exp_add_out)); + +fpu_sub u2( + .clk(clk),.rst(rst),.enable(sub_enable),.opa(opa_reg),.opb(opb_reg), + .fpu_op(fpu_op_reg),.sign(sub_sign),.diff_2(diff_out), + .exponent_2(exp_sub_out)); + +fpu_mul u3( + .clk(clk),.rst(rst),.enable(mul_enable),.opa(opa_reg),.opb(opb_reg), + .sign(mul_sign),.product_7(mul_out),.exponent_5(exp_mul_out)); + +fpu_div u4( + .clk(clk),.rst(rst),.enable(div_enable),.opa(opa_reg),.opb(opb_reg), + .sign(div_sign),.mantissa_7(div_out),.exponent_out(exp_div_out)); + +fpu_round u5(.clk(clk),.rst(rst),.enable(op_enable), .round_mode(rmode_reg), + .sign_term(sign_round),.mantissa_term(mantissa_round), .exponent_term(exponent_round), + .round_out(out_round),.exponent_final(exponent_post_round)); + +fpu_exceptions u6(.clk(clk),.rst(rst),.enable(op_enable),.rmode(rmode_reg), + .opa(opa_reg),.opb(opb_reg), + .in_except(out_round), .exponent_in(exponent_post_round), + .mantissa_in(mantissa_round[1:0]),.fpu_op(fpu_op_reg),.out(out_except), + .ex_enable(except_enable),.underflow(underflow_0),.overflow(overflow_0), + .inexact(inexact_0),.exception(exception_0),.invalid(invalid_0)); + + +always @(posedge clk) +begin + case (fpu_op_reg) + 3'b000: mantissa_round <= addsub_out; + 3'b001: mantissa_round <= addsub_out; + 3'b010: mantissa_round <= mul_out; + 3'b011: mantissa_round <= div_out; + default: mantissa_round <= 0; + endcase +end + +always @(posedge clk) +begin + case (fpu_op_reg) + 3'b000: exponent_round <= exp_addsub; + 3'b001: exponent_round <= exp_addsub; + 3'b010: exponent_round <= exp_mul_out; + 3'b011: exponent_round <= exp_div_out; + default: exponent_round <= 0; + endcase +end + +always @(posedge clk) +begin + case (fpu_op_reg) + 3'b000: sign_round <= addsub_sign; + 3'b001: sign_round <= addsub_sign; + 3'b010: sign_round <= mul_sign; + 3'b011: sign_round <= div_sign; + default: sign_round <= 0; + endcase +end + +always @(posedge clk) +begin + case (fpu_op_reg) + 3'b000: count_cycles <= 20; + 3'b001: count_cycles <= 21; + 3'b010: count_cycles <= 24; + 3'b011: count_cycles <= 71; + default: count_cycles <= 0; + endcase +end + +always @(posedge clk) +begin + if (rst) begin + add_enable <= 0; + sub_enable <= 0; + mul_enable <= 0; + div_enable <= 0; + addsub_out <= 0; + addsub_sign <= 0; + exp_addsub <= 0; + end + else begin + add_enable <= (add_enable_0 | add_enable_1) & op_enable; + sub_enable <= (sub_enable_0 | sub_enable_1) & op_enable; + mul_enable <= (fpu_op_reg == 3'b010) & op_enable; + div_enable <= (fpu_op_reg == 3'b011) & op_enable & enable_reg_3; + // div_enable needs to be high for two clock cycles + addsub_out <= add_enable ? sum_out : diff_out; + addsub_sign <= add_enable ? add_sign : sub_sign; + exp_addsub <= add_enable ? { 1'b0, exp_add_out} : { 1'b0, exp_sub_out}; + end +end + +always @ (posedge clk) +begin + if (rst) + count_ready <= 0; + else if (enable_reg_1) + count_ready <= 0; + else if (count_busy) + count_ready <= count_ready + 1; +end + +always @(posedge clk) +begin + if (rst) begin + enable_reg <= 0; + enable_reg_1 <= 0; + enable_reg_2 <= 0; + enable_reg_3 <= 0; + end + else begin + enable_reg <= enable; + enable_reg_1 <= enable & !enable_reg; + enable_reg_2 <= enable_reg_1; + enable_reg_3 <= enable_reg_1 | enable_reg_2; + end +end + +always @(posedge clk) +begin + if (rst) begin + opa_reg <= 0; + opb_reg <= 0; + fpu_op_reg <= 0; + rmode_reg <= 0; + op_enable <= 0; + end + else if (enable_reg_1) begin + opa_reg <= opa; + opb_reg <= opb; + fpu_op_reg <= fpu_op; + rmode_reg <= rmode; + op_enable <= 1; + end +end + +always @(posedge clk) +begin + if (rst) begin + ready_0 <= 0; + ready_1 <= 0; + ready <= 0; + end + else if (enable_reg_1) begin + ready_0 <= 0; + ready_1 <= 0; + ready <= 0; + end + else begin + ready_0 <= !count_busy; + ready_1 <= ready_0; + ready <= ready_1; + end +end + +always @(posedge clk) +begin + if (rst) begin + underflow <= 0; + overflow <= 0; + inexact <= 0; + exception <= 0; + invalid <= 0; + out <= 0; + end + else if (ready_1) begin + underflow <= underflow_0; + overflow <= overflow_0; + inexact <= inexact_0; + exception <= exception_0; + invalid <= invalid_0; + out <= except_enable ? out_except : out_round; + end +end +endmodule Index: tags/arelease/Readme.txt =================================================================== --- tags/arelease/Readme.txt (nonexistent) +++ tags/arelease/Readme.txt (revision 12) @@ -0,0 +1,130 @@ +The following describes the IEEE-Standard-754 compliant, double-precision floating point unit, +written in Verilog. The module consists of the following files: + +1. fpu_double.v (top level) +2. fpu_add.v +3. fpu_sub.v +4. fpu_mul.v +5. fpu_div.v +6. fpu_round.v +7. fpu_exceptions.v + +And a testbench file is included, containing 50 test-case operations: +1. fpu_tb.v + +This unit has been extensively simulated, covering all operations, rounding modes, exceptions +like underflow and overflow, and even the obscure corner cases, like when overflowing from +denormalized to normalized, and vice-versa. + +The floating point unit supports denormalized numbers, +4 operations (add, subtract, multiply, divide), and 4 rounding +modes (nearest, zero, + inf, - inf). The unit was synthesized with an +estimated frequency of 230 MHz, for a Virtex5 target device. The synthesis results +are below. fpu_double.v is the top-level module, and it contains the input +and output signals from the unit. The unit was designed to be synchronous with +one global clock, and all of the registers can be reset with an synchronous global reset. +When the inputs signals (a and b operands, fpu operation code, rounding mode code) are +available, set the enable input high, then set it low after 2 clock cycles. When the +operation is complete and the output is available, the ready signal will go high. To start +the next operation, set the enable input high. + +Each operation takes the following amount of clock cycles to complete: +1. addition : 20 clock cycles +2. subtraction: 21 clock cycles +3. multiplication: 24 clock cycles +4. division: 71 clock cycles + +This is longer than other floating point units, but supporting denormalized numbers +requires more signals and logic levels to accommodate gradual underflow. The supported +clock speed of 230 MHz makes up for the large number of clock cycles required for each +operation to complete. If you have a lower clock speed, the code can be changed to +reduce the number of registers and latency of each operation. I purposely increased the +number of logic levels to get the code to synthesize to a faster clock frequency, but of course, +this led to longer latency. I guess it depends on your application what is more important. + +The following output signals are also available: underflow, overflow, inexact, exception, +and invalid. They are compliant with the IEEE-754 definition of each signal. The unit +will handle QNaN and SNaN inputs per the standard. + +I'm planning on adding more operations, like square root, sin, cos, tan, etc., +so check back for updates. + +Multiply: +The multiply module is written specifically for a Virtex5 target device. The DSP48E slices +can perform a 25-bit by 18-bit Twos-complement multiply (24 by 17 unsigned multiply). I broke up the multiply to +fit these DSP48E slices. The breakdown is similar to the design in Figure 4-15 of the +Xilinx User Guide Document, "Virtex-5 FPGA XtremeDSP Design Considerations", also known as UG193. +You can find this document at xilinx.com by searching for "UG193". +Depending on your device, the multiply can be changed to match the bit-widths of the available +multipliers. A total of 9 DSP48E slices are used to do the 53-bit by 53-bit multiply of 2 +floating point numbers. + +If you have any questions, please email me at: davidklun@gmail.com + +Thanks, +David Lundgren + +----- + +Synthesis Results: + + + + +Performance Summary +******************* + + +Worst slack in design: -0.971 + + Requested Estimated Requested Estimated Clock Clock +Starting Clock Frequency Frequency Period Period Slack Type Group +----------------------------------------------------------------------------------------------------------- +fpu|clk 300.0 MHz 232.3 MHz 3.333 4.304 -0.971 inferred +========================================================================== + +--------------------------------------- +Resource Usage Report for fpu + +Mapping to part: xc5vsx95tff1136-2 +Cell usage: +DSP48E 9 uses +FD 5 uses +FDR 519 uses +FDRE 3920 uses +FDRSE 1 use +GND 6 uses +LD 6 uses +MUXCY 35 uses +MUXCY_L 704 uses +MUXF7 1 use +VCC 5 uses +XORCY 491 uses +XORCY_L 12 uses +LUT1 185 uses +LUT2 725 uses +LUT3 1523 uses +LUT4 738 uses +LUT5 604 uses +LUT6 2506 uses + +I/O ports: 206 +I/O primitives: 205 +IBUF 135 uses +OBUF 70 uses + +BUFGP 1 use + +I/O Register bits: 0 +Register bits not including I/Os: 4445 (7%) +Latch bits not including I/Os: 6 (0%) + +Global Clock Buffers: 1 of 32 (3%) + +Total load per clock: + fpu|clk: 4454 + +Mapping Summary: +Total LUTs: 6281 (10%) + +

powered by: WebSVN 2.1.0

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