Пример #1
0
        /// <summary>
        /// Converts a double value to its binary encoding, given a floating point format.
        /// </summary>
        /// <param name="value">The value to be encoded</param>
        /// <param name="fmt">The floating point format to be assumed</param>
        /// <returns>The binary encoding</returns>
        public static StdLogicVector ToSLV(this double value, FloatFormat fmt)
        {
            StdLogicVector sign;
            StdLogicVector exponent;
            StdLogicVector mantissa;

            if (double.IsInfinity(value))
            {
                sign     = double.IsNegativeInfinity(value) ? (StdLogicVector)"1" : (StdLogicVector)"0";
                exponent = StdLogicVector._1s(fmt.ExponentWidth);
                mantissa = StdLogicVector._0s(fmt.FractionWidth);
            }
            else if (double.IsNaN(value))
            {
                sign     = (StdLogicVector)"0";
                exponent = StdLogicVector._1s(fmt.ExponentWidth);
                mantissa = StdLogicVector._1s(fmt.FractionWidth);
            }
            else
            {
                sign = value < 0.0 ? (StdLogicVector)"1" : (StdLogicVector)"0";
                double absvalue = Math.Abs(value);
                int    exp      = 0;
                while (absvalue >= 2.0)
                {
                    absvalue *= 0.5;
                    exp++;
                }
                while (absvalue > 0.0 && absvalue < 1.0)
                {
                    absvalue *= 2.0;
                    exp--;
                }
                if (absvalue == 0.0)
                {
                    return(StdLogicVector._0s(fmt.TotalWidth));
                }
                else if (exp <= -fmt.Bias)
                {
                    // denomalized
                    exponent  = StdLogicVector._0s(fmt.ExponentWidth);
                    absvalue *= (double)(1L << (fmt.FractionWidth + 1));
                    long mant = (long)absvalue;
                    mantissa = StdLogicVector.FromLong(mant, fmt.FractionWidth);
                }
                else
                {
                    absvalue -= 1.0;
                    absvalue *= (double)(1L << fmt.FractionWidth);
                    long mant = (long)absvalue;
                    mantissa = StdLogicVector.FromLong(mant, fmt.FractionWidth);
                    exponent = StdLogicVector.FromLong(exp + fmt.Bias, fmt.ExponentWidth);
                }
            }
            return(sign.Concat(exponent.Concat(mantissa)));
        }
Пример #2
0
        /// <summary>
        /// Converts a binary encoding, given as an StdLogicVector with respect to a floating point format to its
        /// double representation.
        /// </summary>
        /// <param name="slv">The binary encoding</param>
        /// <param name="fmt">The floating point format to be assumed</param>
        /// <returns>The double representation</returns>
        public static double ToFloat(this StdLogicVector slv, FloatFormat fmt)
        {
            if (slv.Size != fmt.TotalWidth)
            {
                throw new ArgumentException("Vector does not match specified floating point format");
            }
            slv = slv.ProperValue;

            StdLogicVector mantissa = slv[fmt.FractionWidth - 1, 0];
            StdLogicVector exponent = slv[fmt.FractionWidth + fmt.ExponentWidth - 1, fmt.FractionWidth];
            StdLogic       sign     = slv[fmt.FractionWidth + fmt.ExponentWidth];

            int exp = (int)exponent.ULongValue - fmt.Bias;

            if (exponent.Equals(StdLogicVector._0s(fmt.ExponentWidth)))
            {
                // denormalized
                long   mant   = mantissa.LongValue;
                double result = (double)mant * Math.Pow(2.0, exp - 1);
                return(result);
            }
            else if (exponent.Equals(StdLogicVector._1s(fmt.ExponentWidth)))
            {
                // Infinity / NaN
                if (mantissa.Equals(StdLogicVector._0s(fmt.FractionWidth)))
                {
                    // infinity
                    if (sign == '1')
                    {
                        return(double.NegativeInfinity);
                    }
                    else
                    {
                        return(double.PositiveInfinity);
                    }
                }
                else
                {
                    // NaN
                    return(double.NaN);
                }
            }
            else
            {
                // normalized
                StdLogicVector number = StdLogicVector._1s(1).Concat(mantissa);
                ulong          mant   = number.ULongValue;
                double         result = (double)mant * Math.Pow(2.0, exp - fmt.FractionWidth);
                if (sign == '1')
                {
                    result = -result;
                }
                return(result);
            }
        }
Пример #3
0
        /// <summary>
        /// Converts a double value to its binary encoding, given a floating point format.
        /// </summary>
        /// <param name="value">The value to be encoded</param>
        /// <param name="fmt">The floating point format to be assumed</param>
        /// <returns>The binary encoding</returns>
        public static StdLogicVector ToSLV(this double value, FloatFormat fmt)
        {
            StdLogicVector sign;
            StdLogicVector exponent;
            StdLogicVector mantissa;
            if (double.IsInfinity(value))
            {
                sign = double.IsNegativeInfinity(value) ? (StdLogicVector)"1" : (StdLogicVector)"0";
                exponent = StdLogicVector._1s(fmt.ExponentWidth);
                mantissa = StdLogicVector._0s(fmt.FractionWidth);
            }
            else if (double.IsNaN(value))
            {
                sign = (StdLogicVector)"0";
                exponent = StdLogicVector._1s(fmt.ExponentWidth);
                mantissa = StdLogicVector._1s(fmt.FractionWidth);
            }
            else
            {
                sign = value < 0.0 ? (StdLogicVector)"1" : (StdLogicVector)"0";
                double absvalue = Math.Abs(value);
                int exp = 0;
                while (absvalue >= 2.0)
                {
                    absvalue *= 0.5;
                    exp++;
                }
                while (absvalue > 0.0 && absvalue < 1.0)
                {
                    absvalue *= 2.0;
                    exp--;
                }
                if (absvalue == 0.0)
                {
                    return StdLogicVector._0s(fmt.TotalWidth);
                }
                else if (exp <= -fmt.Bias)
                {
                    // denomalized
                    exponent = StdLogicVector._0s(fmt.ExponentWidth);
                    absvalue *= (double)(1L << (fmt.FractionWidth+1));
                    long mant = (long)absvalue;
                    mantissa = StdLogicVector.FromLong(mant, fmt.FractionWidth);
                }
                else
                {

                    absvalue -= 1.0;
                    absvalue *= (double)(1L << fmt.FractionWidth);
                    long mant = (long)absvalue;
                    mantissa = StdLogicVector.FromLong(mant, fmt.FractionWidth);
                    exponent = StdLogicVector.FromLong(exp + fmt.Bias, fmt.ExponentWidth);
                }
            }
            return sign.Concat(exponent.Concat(mantissa));
        }
        public FloatFormat GetResultFormat()
        {
            FloatFormat fmt;
            switch (ResultPrecision)
            {
                case EPrecision.Single:
                    fmt = FloatFormat.SingleFormat;
                    break;

                case EPrecision.Double:
                    fmt = FloatFormat.DoubleFormat;
                    break;

                case EPrecision.Custom:
                    fmt = new FloatFormat(ResultExponentWidth, ResultFractionWidth);
                    break;

                default:
                    throw new NotImplementedException();
            }
            return fmt;
        }
Пример #5
0
        /// <summary>
        /// Converts a binary encoding, given as an StdLogicVector with respect to a floating point format to its
        /// double representation.
        /// </summary>
        /// <param name="slv">The binary encoding</param>
        /// <param name="fmt">The floating point format to be assumed</param>
        /// <returns>The double representation</returns>
        public static double ToFloat(this StdLogicVector slv, FloatFormat fmt)
        {
            if (slv.Size != fmt.TotalWidth)
                throw new ArgumentException("Vector does not match specified floating point format");
            slv = slv.ProperValue;

            StdLogicVector mantissa = slv[fmt.FractionWidth - 1, 0];
            StdLogicVector exponent = slv[fmt.FractionWidth + fmt.ExponentWidth - 1, fmt.FractionWidth];
            StdLogic sign = slv[fmt.FractionWidth + fmt.ExponentWidth];

            int exp = (int)exponent.ULongValue - fmt.Bias;

            if (exponent.Equals(StdLogicVector._0s(fmt.ExponentWidth)))
            {
                // denormalized
                long mant = mantissa.LongValue;
                double result = (double)mant * Math.Pow(2.0, exp - 1);
                return result;
            }
            else if (exponent.Equals(StdLogicVector._1s(fmt.ExponentWidth)))
            {
                // Infinity / NaN
                if (mantissa.Equals(StdLogicVector._0s(fmt.FractionWidth)))
                {
                    // infinity
                    if (sign == '1')
                        return double.NegativeInfinity;
                    else
                        return double.PositiveInfinity;
                }
                else
                {
                    // NaN
                    return double.NaN;
                }
            }
            else
            {
                // normalized
                StdLogicVector number = StdLogicVector._1s(1).Concat(mantissa);
                ulong mant = number.ULongValue;
                double result = (double)mant * Math.Pow(2.0, exp - fmt.FractionWidth);
                if (sign == '1')
                    result = -result;
                return result;
            }
        }