/* -------------------------------------------------------------------- -- -- -- Copyright©2002 by the Institute of Electrical and Electronics Engineers, Inc. -- Three Park Avenue -- New York, NY 10016-5997, USA -- All rights reserved. -- -- This document is an unapproved draft of a proposed IEEE Standard. As such, -- this document is subject to change. USE AT YOUR OWN RISK! Because this -- is an unapproved draft, this document must not be utilized for any -- conformance/compliance purposes. Permission is hereby granted for IEEE -- Standards Committee participants to reproduce this document for purposes -- of IEEE standardization activities only. Prior to submitting this document -- to another standards development organization for standardization -- activities, permission must first be obtained from the Manager, Standards -- Licensing and Contracts, IEEE Standards Activities Department. Other -- entities seeking permission to reproduce this document, in whole or in -- part, must obtain permission from the Manager, Standards Licensing and -- Contracts, IEEE Standard Activities Department. -- -- IEEE Standards Activities Department -- Standards Licensing and Contracts -- 445 Hoes Lane, P.O. Box 1331 -- Piscataway, NJ 08855-1331, USA -- -- Title : FPHDL_PKG < IEEE std # 1076.3 > -- -- Developers: VHDL Synthesis working group, PAR 1076.3 -- -- Purpose : Basic floating point operations for Verilog -- Calls the VHDL to perform operations. -- -- Limitation: Needs to co-simulate with VHDL floating point packages. -- -- -------------------------------------------------------------------- -- Last Modified $Date: 2003-10-20 15:01:08-04 $ $Id: fphdl32_vhdlcos_pkg.v,v 1.7 2003-10-20 15:01:08-04 bishop Exp $ -- modification history : $Log: fphdl32_vhdlcos_pkg.v,v $ -- modification history : Revision 1.7 2003-10-20 15:01:08-04 bishop -- modification history : Added a parameter to turn error checking off -- modification history : -- modification history : Revision 1.6 2003-07-29 15:34:01-04 bishop -- modification history : Added oneoverx, dividebyp2, polar_to_complex and complex_to_polar modules -- modification history : -- modification history : Revision 1.5 2003-01-15 09:04:02-05 bishop -- modification history : Modified to use a generic VHDL package -- modification history : -- modification history : Revision 1.4 2003-01-03 13:15:05-05 bishop -- modification history : Changed the parameter "size" to "width". -- modification history : -- modification history : Revision 1.3 2003-01-02 16:41:56-05 bishop -- modification history : Updated for the latest parameters in the VHDL packages -- modification history : -- modification history : Revision 1.2 2003-01-02 09:41:38-05 bishop -- modification history : Updated mostly with comments -- modification history : -- modification history : Revision 1.1 2002-12-31 16:28:59-05 bishop -- modification history : Initial revision -- modification history : -- -------------------------------------------------------------------- */ /* suggested parameters parameter fraction_width = 23; //length of FP fraction parameter exponent_width = 8; //length of FP exponent parameter check_error = 1; //check error = true (turn NAN checking on) parameter ieee_extend = 1; //Use IEEE extended FP = true parameter round_style = 0; //rounding option = round_nearest */ /* Author: David Bishop dbishop@vhdl.org */ /* This version of the Verilog packages called the VHDL packages. */ module fp32_abs (res, arg); // absolute number output [31:0] res; input [31:0] arg; absolute_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_abs module fp32_neg (res, arg); // unary negative output [31:0] res; input [31:0] arg; negative_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_neg module fp32_add (res, l, r); // addition (l + r) output [31:0] res; input [31:0] l, r; addition_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_add module fp32_add_c (res_r, res_i, l_r, l_i, r_r, r_i); // complex add output [31:0] res_r, res_i; // _r = real _i = imaginary input [31:0] l_r, l_i, r_r, r_i; complex_add_ea #(23,8,1,1,0) u1 ( .res_r(res_r), .res_i(res_i), .l_r(l_r), .l_i(l_i), .r_r(r_r), .r_i(r_i)); endmodule // fp32_add_c module fp32_sub (res, l, r); // subtraction (l - r) output [31:0] res; input [31:0] l, r; subtract_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_sub module fp32_sub_c (res_r, res_i, l_r, l_i, r_r, r_i); // complex subtraction output [31:0] res_r, res_i; // _r = real _i = imaginary input [31:0] l_r, l_i, r_r, r_i; complex_subtract_ea #(23,8,1,1,0) u1 ( .res_r(res_r), .res_i(res_i), .l_r(l_r), .l_i(l_i), .r_r(r_r), .r_i(r_i)); endmodule // fp32_sub_c module fp32_mul (res, l, r); // multiplation (l * r) output [31:0] res; input [31:0] l, r; multiply_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_mul module fp32_mul_c (res_r, res_i, l_r, l_i, r_r, r_i); // complex multiplicaiton output [31:0] res_r, res_i; // _r = real _i = imaginary input [31:0] l_r, l_i, r_r, r_i; complex_multiply_ea #(23,8,1,1,0) u1 ( .res_r(res_r), .res_i(res_i), .l_r(l_r), .l_i(l_i), .r_r(r_r), .r_i(r_i)); endmodule // fp32_mul_c module fp32_div (res, l, r); // division (l / r) output [31:0] res; input [31:0] l, r; divide_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_div module fp32_div_c (res_r, res_i, l_r, l_i, r_r, r_i); // complex division output [31:0] res_r, res_i; // _r = real _i = imaginary input [31:0] l_r, l_i, r_r, r_i; complex_divide_ea #(23,8,1,1,0) u1 ( .res_r(res_r), .res_i(res_i), .l_r(l_r), .l_i(l_i), .r_r(r_r), .r_i(r_i)); endmodule // fp32_div_c module fp32_oneoverx (res, arg); // 1/arg output [31:0] res; input [31:0] arg; oneoverx_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_oneoverx module fp32_rem (res, l, r); // remainder output [31:0] res; input [31:0] l, r; remainder_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_rem module fp32_divbyp2 (res, l, r); // division (l / r) output [31:0] res; input [31:0] l, r; dividebyp2_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_divbyp2 module fp32_complex_to_polar (res_mag, res_angle, arg_r, arg_i); // complex_to_plar output [31:0] res_mag, res_angle; input [31:0] arg_r, arg_i; // _r = real _i = imaginary complex_to_polar_ea #(23,8,1,1,0) u1 ( .res_mag(res_mag), .res_angle(res_angle), .arg_r(arg_r), .arg_i(arg_i)); endmodule // fp32_complex_to_polar module fp32_polar_to_complex (res_r, res_i, arg_mag, arg_angle); // polar to complex output [31:0] res_r, res_i; // _r = real _i = imaginary input [31:0] arg_mag, arg_angle; polar_to_complex_ea #(23,8,1,1,0) u1 ( .res_r(res_r), .res_i(res_i), .arg_mag(arg_mag), .arg_angle(arg_angle)); endmodule // fp32_complex_to_polar module fp32_sqrt (res, arg); // square root output [31:0] res; input [31:0] arg; square_root_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_sqrt module fp32_log (res, base, arg); // log output [31:0] res; input [31:0] base; input [31:0] arg; log_ea #(23,8,1,1,0) u1 ( .res(res), .base(base), .arg(arg)); endmodule // fp32_log module fp32_ln (res, arg); // ln output [31:0] res; input [31:0] arg; natural_log_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_ln module fp32_pow_fp (res, l, r); // l**r, where l and r are fp32 output [31:0] res; input [31:0] l, r; power_of_fp_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_pow_fp module fp32_pow (res, l, r); // l**r, where l is fp32 and r is integer output [31:0] res; input [31:0] r; // integer input [31:0] l; power_of_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_pow module fp32_sin (res, arg); // sin output [31:0] res; input [31:0] arg; sine_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_sin module fp32_cos (res, arg); // cos output [31:0] res; input [31:0] arg; cosine_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_cos module fp32_tan (res, arg); // tan output [31:0] res; input [31:0] arg; tangent_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_tan module fp32_arc_sin (res, arg); // arcsin output [31:0] res; input [31:0] arg; arc_sine_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_arc_sin module fp32_arc_cos (res, arg); // arccos output [31:0] res; input [31:0] arg; arc_cosine_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_arc_cos module fp32_arc_tan (res, arg); // arctan output [31:0] res; input [31:0] arg; arc_tangent_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_arc_tan module fp32_equ (res, l, r); // = output res; input [31:0] l, r; equal_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_equ module fp32_not_equ (res, l, r); // != output res; input [31:0] l, r; not_equal_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_not_equ module fp32_gteq (res, l, r); // >= output res; input [31:0] l, r; greater_than_or_equal_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_gteq module fp32_lteq (res, l, r); // <= output res; input [31:0] l, r; less_than_or_equal_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_lteq module fp32_gt (res, l, r); // > output res; input [31:0] l, r; greater_than_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_gt module fp32_lt (res, l, r); // < output res; input [31:0] l, r; less_than_ea #(23,8,1,1,0) u1 ( .res(res), .l(l), .r(r)); endmodule // fp32_lt module integer_to_fp32 (res, arg); // integer input, fp32 output output [31:0] res; // floating point input [31:0] arg; // integer integer_to_fp_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // to_fp32 module real_to_fp32 (res, arg); // real input, fp32 output output [31:0] res; // floating point input [63:0] arg; // Verilog real number real_to_fp_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // to_fp32 /* assign arg = $realtobits(r); from Cadence's Verilog-XL Reference Manual chap. 11 : "Real Numbers in Port Connections The real data type cannot be directly connected to a port. Rather it must be connected indirectly, as shown in the following example. The system functions $realtobits and $bitstoreal are used for passing the bit patterns across the module ports. module driver (net_r); output net_r; real r; wire [64:1] net_r = $realtobits(r); endmodule module receiver (net_r); input net_r; wire [64:1] net_r; real r; initial assign r =$bitstoreal(net_r); endmodule " */ module signed_to_fp32 (res, arg);// signed, parameter: width parameter width = 32; output [31:0] res; // floating point input [width-1:0] arg; signed_to_fp_ea #(width,23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // signed_to_fp32 module unsigned_to_fp32 (res, arg); // unsigned, parameter: width parameter width = 32; output [31:0] res; // floating point input [width-1:0] arg; unsigned_to_fp_ea #(width,23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // unsigned_to_fp32 module fp32_to_integer (res, arg); // fp32 to integer output [31:0] res; // integer input [31:0] arg; // floating point fp_to_integer_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // to_integer module fp32_to_unsigned (res, arg); // fp32 to unsigned, parameter: width parameter width = 32; output [width-1:0] res; // floating point input [31:0] arg; fp_to_unsigned_ea #(width,23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_to_unsigned module fp32_to_signed (res, arg); // fp32 to signed, parameter: width parameter width = 32; output [width-1:0] res; // floating point input [31:0] arg; fp_to_signed_ea #(width,23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_to_signed module fp32_to_real (res, arg); // fp32 to real output [63:0] res; // Verilog real number input [31:0] arg; // floating point fp_to_real_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_to_real /* use: assign res = $bitstoreal(arg); See real_to_fp32 above */ module fp32_Copysign (res, x, y); // copies sign of x to y output [31:0] res; input [31:0] x, y; Copysign_ea #(23,8,1,1,0) u1 ( .res(res), .x(x), .y(y)); endmodule // fp32_Copysign module fp32_Scalb (res, y, n); // multiplies y by 2**n (where n is an integer) output [31:0] res; input [31:0] y; input [31:0] n; Scalb_ea #(23,8,1,1,0) u1 ( .res(res), .y(y), .n(n)); endmodule // fp32_Scalb module fp32_Logb (res, arg); // returns the log (base 2) of arg output [31:0] res; // integer input [31:0] arg; Logb_ea #(23,8,1,1,0) u1 ( .res(res), .arg(arg)); endmodule // fp32_Logb module fp32_Nextafter (res, x, y); // Gives you the next logical number after x output [31:0] res; input [31:0] x, y; Nextafter_ea #(23,8,1,1,0) u1 ( .res(res), .x(x), .y(y)); endmodule // fp32_Nextafter module fp32_Finite (res, x); // returns "1" if x is not infinity. output res; input [31:0] x; Finite_ea #(23,8,1,1,0) u1 ( .res(res), .x(x)); endmodule // fp32_Finite module fp32_Isnan (res, x); // returns "1" is x in any type of NAN output res; input [31:0] x; Isnan_ea #(23,8,1,1,0) u1 ( .res(res), .x(x)); endmodule // fp32_Isnan module fp32_Class (res, x); output [3:0] res; input [31:0] x; Class_ea #(23,8,1,1,0) u1 ( .res(res), .x(x)); endmodule // fp32_Class module fp32_Unordered (res, x, y); // returns "1" if x or y is a NAN. output res; input [31:0] x, y; Unordered_ea #(23,8,1,1,0) u1 ( .res(res), .x(x), .y(y)); endmodule // fp32_Unordered