Esempio n. 1
0
        private void HandleSinOrCos(XILSInstr i)
        {
            FixFormat oformat, rformat;

            IsFix(i.OperandTypes[0], out oformat);
            IsFix(i.ResultTypes[0], out rformat);
            var preds = RemapPreds(i.Preds);

            if (oformat == null)
            {
                Emit(i.Command.CreateStk(preds, 1, i.OperandTypes[0], i.ResultTypes[0]));
            }
            else
            {
                TypeDescriptor otype = i.OperandTypes[0];
                if (!i.OperandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var itype = SFix.MakeType(oformat.IntWidth + 1, oformat.FracWidth);
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, i.OperandTypes, i.ResultTypes));
                    preds = new InstructionDependency[0];
                    otype = itype;
                }
                var nrtype = SFix.MakeType(2, rformat.FracWidth);
                Emit(i.Command.CreateStk(preds, 1, otype, nrtype));
                if (!i.ResultTypes[0].Equals(nrtype))
                {
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, nrtype, i.ResultTypes[0]));
                }
            }
        }
Esempio n. 2
0
        public static void SubstituteLU(SFix[,] LU, SFix[] b, SFix[] y, SFix[] x)
        {
            int n = LU.GetLength(0);


            for (int i = 0; i < n; i++)
            {
                x[i] = b[i];
            }

            /* do forward substitution, replacing x vector. */

            x[0] /= LU[0, 0];
            for (int i = 1; i < n; i++)
            {
                SFix sum = SFix.FromLong(0, 1);
                for (int j = 0; j < i; j++) sum += LU[i, j] * x[j];
                x[i] = (x[i] - sum) / LU[i, i];
            }

            /* now get the solution vector, x[n-1] is already done */

            for (int i = n - 2; i >= 0; i--)
            {
                SFix sum = SFix.FromLong(0, 1);
                for (int j = i + 1; j < n; j++) sum += LU[i, j] * x[j];
                x[i] -= sum;
            }
        }
Esempio n. 3
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu  = taSite.Host;
            var scc = fu as SinCosLUTCore;

            if (scc == null)
            {
                yield break;
            }

            if (operandTypes.Length != 1 || resultTypes.Length != 2)
            {
                yield break;
            }

            var xType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.XIntWidth, scc.XFracWidth));
            var yType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.YIntWidth, scc.YFracWidth));

            if (!operandTypes[0].Equals(xType) ||
                !resultTypes[0].Equals(yType) ||
                !resultTypes[1].Equals(yType))
            {
                yield break;
            }

            if (instr.Name != InstructionCodes.ScSinCos)
            {
                yield break;
            }

            yield return(new Mapping(scc));
        }
Esempio n. 4
0
        public static void SubstituteLU(SFix[,] LU, SFix[] b, SFix[] y, SFix[] x)
        {
            int n = LU.GetLength(0);


            for (int i = 0; i < n; i++)
            {
                x[i] = b[i];
            }

            /* do forward substitution, replacing x vector. */

            x[0] /= LU[0, 0];
            for (int i = 1; i < n; i++)
            {
                SFix sum = SFix.FromLong(0, 1);
                for (int j = 0; j < i; j++)
                {
                    sum += LU[i, j] * x[j];
                }
                x[i] = (x[i] - sum) / LU[i, i];
            }

            /* now get the solution vector, x[n-1] is already done */

            for (int i = n - 2; i >= 0; i--)
            {
                SFix sum = SFix.FromLong(0, 1);
                for (int j = i + 1; j < n; j++)
                {
                    sum += LU[i, j] * x[j];
                }
                x[i] -= sum;
            }
        }
Esempio n. 5
0
        private async void TestProcess()
        {
            _nxt = false;

            await Tick;

            double a = 100.0;
            double b = 1.0;

            while (true)
            {
                //ProgramFlow.DoNotUnroll();

                _dividend = SFix.FromDouble(a, iw, fw);
                _divisor = SFix.FromDouble(b, iw, fw);
                _nxt = true;
                while (_rdy)
                {
                    //ProgramFlow.DoNotUnroll();
                    await Tick;
                }
                _nxt = false;
                while (!_rdy)
                {
                    //ProgramFlow.DoNotUnroll();
                    await Tick;
                }

                Console.WriteLine(_dividend.DoubleValue + " / " + _divisor.DoubleValue + " = " + _quotient.DoubleValue);
                b = b + 1.0;
            }
        }
Esempio n. 6
0
        public static string Convert_SLV_SFix(string value, TypeDescriptor ttype)
        {
            FixFormat fmt = SFix.GetFormat(ttype);

            return("lv_to_fixed(" + value + ", sc_fixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (0))");
            //return "sc_fixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (sc_bigint<" + fmt.TotalWidth + ">(" + value + "))";
        }
Esempio n. 7
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            if (operandTypes.Length != 1 || resultTypes.Length != 2)
            {
                return(null);
            }

            if (!operandTypes[0].CILType.Equals(typeof(SFix)) ||
                !resultTypes[0].CILType.Equals(typeof(SFix)) ||
                !resultTypes[1].Equals(resultTypes[0]))
            {
                return(null);
            }

            var xfmt = SFix.GetFormat(operandTypes[0]);
            var yfmt = SFix.GetFormat(resultTypes[0]);

            int lutWidth   = Math.Max(1, xfmt.FracWidth - 1);
            int mulWidth   = Math.Max(1, xfmt.FracWidth - lutWidth);
            int pipeStages = 0; // 2 * mulWidth * mulWidth / (18 * 18) + yfmt.FracWidth / 18 + 1;
            var scc        = new SinCosLUTCore(lutWidth, xfmt.FracWidth, yfmt.FracWidth, pipeStages);

            var mappings = TryMap(scc.TASite, instr, operandTypes, resultTypes);

            Debug.Assert(mappings.Any());
            return(mappings.First());
        }
Esempio n. 8
0
        //********************************************************************************************************************
        //*******************Hier wird die angegebene Dezimalzahl im Binaere umgewandelt**************************************
        //int intw;
        private StdLogicVector Getbinaer(double x)
        {
            StdLogicVector v = SFix.FromDouble(x, 2, OutputWidth - 2).SignedValue.SLVValue;

            //double y = SFix.FromSigned(v.SignedValue, 10).DoubleValue;
            return(v);
        }
Esempio n. 9
0
        private void ArgsProcess()
        {
            UFix x, xd, xq;

            _sinFlipSignIn.Next = "0";
            _cosFlipSignIn.Next = "0";
            if (X.Cur[XFracWidth + 1] == '1')
            {
                // x is negative
                x = (-SFix.FromSigned(X.Cur.SignedValue, XFracWidth - LUTWidth - 1)).UFixValue.Resize(LUTWidth + 2, XFracWidth - LUTWidth - 1);
                _sinFlipSignIn.Next = "1";
            }
            else
            {
                // x is non-negative
                x = UFix.FromUnsigned(X.Cur[XFracWidth, 0].UnsignedValue, XFracWidth - LUTWidth - 1);
            }
            if (x.SLVValue[XFracWidth] == '1' || x.SLVValue[XFracWidth - 1] == '1')
            {
                // between Pi/2 and Pi
                xd = (_mirror - x).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1);
                xq = (x - _mirror2).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1);
                _cosFlipSignIn.Next = "1";
            }
            else
            {
                xd = x.Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1);
                xq = (_mirror2 - x).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1);
            }
            _x.Next  = xd;
            _xq.Next = xq;
        }
Esempio n. 10
0
        private static TypeDescriptor MakeUFixSFix(TypeDescriptor t)
        {
            var fmt = UFix.GetFormat(t);
            var smp = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth);

            return(TypeDescriptor.GetTypeOf(smp));
        }
Esempio n. 11
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes
        /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertLong(long src, TypeDescriptor dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(Signed)))
            {
                return(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(Unsigned)))
            {
                return(Unsigned.FromBigInt(new System.Numerics.BigInteger(src), UFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(SFix)))
            {
                return(SFix.FromSigned(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth), SFix.GetFormat(dstType).FracWidth));
            }
            else if (dstType.CILType.Equals(typeof(StdLogicVector)))
            {
                return(StdLogicVector.FromLong(src, StdLogicVector.GetLength(dstType)));
            }
            else
            {
                return(ConvertLong(src, dstType.CILType));
            }
        }
Esempio n. 12
0
 private void DiagMonSFix()
 {
     if (Clk.RisingEdge() && EnIn.Cur == '1')
     {
         Console.WriteLine("Writing variable " + MappedVariableName + ": " + SFix.FromSigned(DIn.Cur.SignedValue, _fracWidth).DoubleValue);
     }
 }
Esempio n. 13
0
        private async void TestProcess()
        {
            _nxt = false;

            await Tick;

            double a = 100.0;
            double b = 1.0;

            while (true)
            {
                //ProgramFlow.DoNotUnroll();

                _dividend = SFix.FromDouble(a, iw, fw);
                _divisor  = SFix.FromDouble(b, iw, fw);
                _nxt      = true;
                while (_rdy)
                {
                    //ProgramFlow.DoNotUnroll();
                    await Tick;
                }
                _nxt = false;
                while (!_rdy)
                {
                    //ProgramFlow.DoNotUnroll();
                    await Tick;
                }

                Console.WriteLine(_dividend.DoubleValue + " / " + _divisor.DoubleValue + " = " + _quotient.DoubleValue);
                b = b + 1.0;
            }
        }
Esempio n. 14
0
 public void TestFromToDouble()
 {
     Assert.AreEqual(0.0, SFix.FromDouble(0.0, 1, 1).DoubleValue, "conversion from/to 0 failed.");
     Assert.AreEqual(1.0, SFix.FromDouble(1.0, 2, 0).DoubleValue, "conversion from/to 1 failed.");
     Assert.AreEqual(-1.0, SFix.FromDouble(-1.0, 2, 0).DoubleValue, "conversion from/to -1 failed.");
     Assert.AreEqual(1.0, SFix.FromDouble(1.5, 3, 0).DoubleValue, "conversion from/to 1 failed.");
     Assert.AreEqual(-1.5, SFix.FromDouble(-1.5, 2, 1).DoubleValue, "conversion from/to 1.6 failed.");
 }
Esempio n. 15
0
        public static SFix Cos(SFix value, int fracWidth)
        {
            Contract.Requires <ArgumentOutOfRangeException>(fracWidth >= 0, "fracWidth");

            return(SFix.FromDouble(
                       Math.Cos(value.DoubleValue),
                       2,
                       fracWidth));
        }
Esempio n. 16
0
        public static SFix Cos(SFix value)
        {
            Contract.Requires <ArgumentOutOfRangeException>(value.Format.FracWidth >= 0, "value.Format.FracWidth");

            return(SFix.FromDouble(
                       Math.Sin(value.DoubleValue),
                       2,
                       value.Format.FracWidth));
        }
Esempio n. 17
0
            private async void Processing()
            {
                await Tick;
                var   aux = SFix.FromDouble(0.5, 1, 1);
                SFix  aux1;

                Ctr.Next  = _ctr.Cur;
                aux1      = _ctr.Cur + aux;
                _ctr.Next = aux1.Resize(7, 1);
            }
Esempio n. 18
0
        /*
         * Code partially ported from:
         *
         * Chapter 2, Programs 3-5, Fig. 2.8-2.10
         * Gerald/Wheatley, APPLIED NUMERICAL ANALYSIS (fourth edition)
         * Addison-Wesley, 1989
         */

        public static void ComputeLU(SFix[,] A, int iw, int fw)
        {
            int n = A.GetLength(0);

            SFix sum;
            SFix diag = (SFix.FromLong(1, iw, fw) / A[0, 0]).Resize(iw, fw);

            for (int i = 1; i < n; i++)
            {
                A[0, i] = (A[0, i] * diag).Resize(iw, fw);
            }

            /*
             *  Now complete the computing of L and U elements.
             *  The general plan is to compute a column of L's, then
             *  call pivot to interchange rows, and then compute
             *  a row of U's.
             */

            int nm1 = n - 1;

            for (int j = 1; j < nm1; j++)
            {
                /* column of L's */
                for (int i = j; i < n; i++)
                {
                    sum = SFix.FromLong(0, iw, fw);
                    for (int k = 0; k < j; k++)
                    {
                        sum = (sum + A[i, k] * A[k, j]).Resize(iw, fw);
                    }
                    A[i, j] = (A[i, j] - sum).Resize(iw, fw);
                }
                /* row of U's */
                diag = (SFix.FromLong(1, iw, fw) / A[j, j]).Resize(iw, fw);
                for (int k = j + 1; k < n; k++)
                {
                    sum = SFix.FromLong(0, iw, fw);
                    for (int i = 0; i < j; i++)
                    {
                        sum = (sum + A[j, i] * A[i, k]).Resize(iw, fw);
                    }
                    A[j, k] = ((A[j, k] - sum) * diag).Resize(iw, fw);
                }
            }

            /* still need to get last element in L Matrix */

            sum = SFix.FromLong(0, iw, fw);
            for (int k = 0; k < nm1; k++)
            {
                sum = (sum + A[nm1, k] * A[k, nm1]).Resize(iw, fw);
            }
            A[nm1, nm1] = (A[nm1, nm1] - sum).Resize(iw, fw);
        }
Esempio n. 19
0
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        /// <param name="floatWidth">total bit-width of input floating-point number
        /// (actual partitioning between exponent and mantissa bits does not matter)</param>
        /// <param name="outFormat">desired fixed-point output format</param>
        public FloatSignAsSigned(int floatWidth, FixFormat outFormat)
        {
            FloatWidth = floatWidth;
            OutFormat  = outFormat;

            _outM1 = SFix.FromDouble(-1.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue;
            _out0  = SFix.FromDouble(0.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue;
            _out1  = SFix.FromDouble(1.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue;
            _zeros = StdLogicVector._0s(floatWidth - 1);

            TASite = new TransactionSite(this);
        }
Esempio n. 20
0
        private void HandleScSinCos(XILSInstr i)
        {
            var preds  = RemapPreds(i.Preds);
            var infmt  = i.OperandTypes[0].GetFixFormat();
            var outfmt = i.ResultTypes[0].GetFixFormat();

            if (infmt == null)
            {
                Emit(i.Command.CreateStk(preds, i.OperandTypes, i.ResultTypes));
            }
            else
            {
                var otype = i.OperandTypes[0];
                if (HaveXilinxCordic && infmt.IntWidth != 3)
                {
                    // Xilinx Cordic needs exactly 3 integer bits for operand
                    otype = SFix.MakeType(3, infmt.FracWidth);
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(
                             preds, 1, i.OperandTypes[0], otype));
                }
                else if (infmt.IntWidth != 2)
                {
                    // Any reasonable core (e.g. LUT-based implementation) will require 2 integer operand bits
                    otype = SFix.MakeType(2, infmt.FracWidth);
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(
                             preds, 1, i.OperandTypes[0], otype));
                }
                preds = new InstructionDependency[0];
                var rtype = i.ResultTypes[0];
                if (outfmt.IntWidth != 2)
                {
                    // we gonna need exactly 2 integer bits for results
                    rtype = SFix.MakeType(2, outfmt.FracWidth);
                }
                Emit(DefaultInstructionSet.Instance.ScSinCos().CreateStk(
                         preds, 1, otype, rtype, rtype));
                if (!rtype.Equals(i.ResultTypes[1]))
                {
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(
                             1, rtype, i.ResultTypes[1]));
                }
                if (!rtype.Equals(i.ResultTypes[0]))
                {
                    Emit(DefaultInstructionSet.Instance.Swap().CreateStk(
                             2, i.ResultTypes[0], rtype, rtype, i.ResultTypes[0]));
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(
                             1, rtype, i.ResultTypes[0]));
                    Emit(DefaultInstructionSet.Instance.Swap().CreateStk(
                             2, rtype, rtype, rtype, rtype));
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertSigned(Signed src, Type dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.Equals(typeof(double)))
            {
                return(SFix.FromSigned(src, 0).DoubleValue);
            }
            else
            {
                return(ConvertValue(src.LongValue, dstType));
            }
        }
Esempio n. 22
0
 public static Signed SignedSign(SFix number)
 {
     if (number < SFix.Zero)
     {
         return(Signed.FromInt(-1, 2));
     }
     else if (number > SFix.Zero)
     {
         return(Signed.FromInt(1, 2));
     }
     else
     {
         return(Signed.FromInt(0, 2));
     }
 }
Esempio n. 23
0
        private async void StimulateAndTest()
        {
            DesignContext.Instance.FixPoint.DefaultRadix = 10;

            for (double i = -1.0; i <= 1.0; i += 0.0625)
            {
                var x = SFix.FromDouble(i, 2, _xFracWidth);
                _x.Next = x.SLVValue;
                //DesignContext.Wait(_pipeStages + 4);
                await NTicks(_pipeStages + 3);

                Console.WriteLine("X = " + x +
                                  ", Sin = " + SFix.FromSigned(_sin.Cur.SignedValue, _yFracWidth) +
                                  ", Cos = " + SFix.FromSigned(_cos.Cur.SignedValue, _yFracWidth));
            }
        }
Esempio n. 24
0
        public static void RunTest()
        {
            DesignContext.Reset();
            FixedPointSettings.GlobalArithSizingMode = EArithSizingMode.VHDLCompliant;

            var a = SFix.FromDouble(1.0, 8, 10);
            var b = SFix.FromDouble(2.0, 8, 10);
            var c = SFix.FromDouble(3.0, 8, 10);
            var d = SFix.FromDouble(4.0, 8, 10);

            TestAddMul2 dut = new TestAddMul2()
            {
                Clk = new SLSignal(),
                A   = new Signal <SFix>()
                {
                    InitialValue = a
                },
                B = new Signal <SFix>()
                {
                    InitialValue = b
                },
                C = new Signal <SFix>()
                {
                    InitialValue = c
                },
                D = new Signal <SFix>()
                {
                    InitialValue = d
                },
                R = new Signal <SFix>()
                {
                    InitialValue = a * b + c * d
                }
            };

            DesignContext.Instance.Elaborate();
            XilinxIntegration.RegisterIPCores(DesignContext.Instance.Descriptor);
            DesignContext.Instance.CompleteAnalysis();

            XC6VLX240T_FF1156 fpga = new XC6VLX240T_FF1156()
            {
                SpeedGrade        = ESpeedGrade._2,
                TopLevelComponent = dut
            };

            fpga.Synthesize(@".\hdl_out_TestAddMul2", "TestAddMul2");
        }
Esempio n. 25
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes
        /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertSigned(Signed src, TypeDescriptor dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(Signed)))
            {
                return(src.Resize(SFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(SFix)))
            {
                return(SFix.FromSigned(src.Resize(SFix.GetFormat(dstType).TotalWidth), SFix.GetFormat(dstType).FracWidth));
            }
            else
            {
                return(ConvertSigned(src, dstType.CILType));
            }
        }
Esempio n. 26
0
        private async void LERPProcess()
        {
            await Tick;

            while (true)
            {
                Addr.Next = X.Cur.GetIntPart().Resize(AddrWidth);
                SFix  alpha = UFix.FromUnsigned(X.Cur.GetFracPart(), XFracWidth).SFixValue;
                await Tick;
                SFix  v0 = Data.Cur;
                Addr.Next = (X.Cur.GetIntPart() + Unsigned.One).Resize(AddrWidth);
                await Tick;
                SFix  v1 = Data.Cur;
                _yIn.Next = (v0 + alpha * (v1 - v0)).Resize(YIntWidth, YFracWidth).SLVValue;
                await PipeStages.Ticks();
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        /// <param name="xIntWidth">integer bits of operand</param>
        /// <param name="xFracWidth">fractional bits of operand</param>
        /// <param name="yIntWidth">integer bits of result</param>
        /// <param name="yFracWidth">fractional bits of result</param>
        /// <param name="pipeStages">desired computation-only latency</param>
        /// <param name="data">data table</param>
        public LERP11Core(int xIntWidth, int xFracWidth, int yIntWidth, int yFracWidth, int pipeStages,
                          SFix[] data)
        {
            Contract.Requires <ArgumentOutOfRangeException>(xIntWidth > 0, "xIntWidth must be positive.");
            Contract.Requires <ArgumentOutOfRangeException>(xFracWidth >= 0, "xFracWidth must be non-negative.");
            Contract.Requires <ArgumentOutOfRangeException>(yIntWidth + yFracWidth > 0, "total bit-width of result must be positive");
            Contract.Requires <ArgumentOutOfRangeException>(pipeStages >= 0, "pipeStages must be non-negative.");
            Contract.Requires <ArgumentOutOfRangeException>(xFracWidth > 0 || pipeStages == 0, "xFracWidth == 0 is a degenerate case (lookup-only). No additional pipeline stages allowed.");
            Contract.Requires <ArgumentNullException>(data != null, "data");

            PipeStages = pipeStages;
            XIntWidth  = xIntWidth;
            XFracWidth = xFracWidth;
            YIntWidth  = yIntWidth;
            YFracWidth = yFracWidth;
            DIntWidth  = data[0].Format.IntWidth;
            DFracWidth = data[0].Format.FracWidth;

            _x = new Signal <UFix>()
            {
                InitialValue = UFix.FromDouble(0.0, xIntWidth, xFracWidth)
            };
            _y = new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, yIntWidth, yFracWidth)
            };
            AddrWidth = MathExt.CeilPow2(data.Length);
            _unitAddr = new Signal <Unsigned>()
            {
                InitialValue = Unsigned.FromUInt(0, AddrWidth)
            };
            _memContent = new VSignal <SFix>(data.Length, _ => new Signal <SFix>()
            {
                InitialValue = data[_]
            });

            _lerpUnit = new LERPUnit(xIntWidth, xFracWidth, yIntWidth, yFracWidth, pipeStages);
            Bind(() =>
            {
                _lerpUnit.Clk  = Clk;
                _lerpUnit.X    = _x;
                _lerpUnit.Y    = _y;
                _lerpUnit.Addr = _unitAddr;
                _lerpUnit.Data = _unitData;
            });
        }
Esempio n. 28
0
        /*
         * Code partially ported from:
         * 
         * Chapter 2, Programs 3-5, Fig. 2.8-2.10
         * Gerald/Wheatley, APPLIED NUMERICAL ANALYSIS (fourth edition)
         * Addison-Wesley, 1989
         */
        
        public static void ComputeLU(SFix[,] A, int iw, int fw)
        {
            int n = A.GetLength(0);

            SFix sum;
            SFix diag = (SFix.FromLong(1, iw, fw) / A[0, 0]).Resize(iw, fw);
            for (int i = 1; i < n; i++) 
                A[0, i] = (A[0, i] * diag).Resize(iw, fw);

            /* 
            *  Now complete the computing of L and U elements.
            *  The general plan is to compute a column of L's, then
            *  call pivot to interchange rows, and then compute
            *  a row of U's.
            */

            int nm1 = n - 1;
            for (int j = 1; j < nm1; j++)
            {
                /* column of L's */
                for (int i = j; i < n; i++)
                {
                    sum = SFix.FromLong(0, iw, fw);
                    for (int k = 0; k < j; k++) 
                        sum = (sum + A[i, k] * A[k, j]).Resize(iw, fw);
                    A[i, j] = (A[i, j] - sum).Resize(iw, fw);
                }
                /* row of U's */
                diag = (SFix.FromLong(1, iw, fw) / A[j, j]).Resize(iw, fw);
                for (int k = j + 1; k < n; k++)
                {
                    sum = SFix.FromLong(0, iw, fw);
                    for (int i = 0; i < j; i++) 
                        sum = (sum + A[j, i] * A[i, k]).Resize(iw, fw);
                    A[j, k] = ((A[j, k] - sum) * diag).Resize(iw, fw);
                }
            }

            /* still need to get last element in L Matrix */

            sum = SFix.FromLong(0, iw, fw);
            for (int k = 0; k < nm1; k++) 
                sum = (sum + A[nm1, k] * A[k, nm1]).Resize(iw, fw);
            A[nm1, nm1] = (A[nm1, nm1] - sum).Resize(iw, fw);
        }
Esempio n. 29
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertSFix(SFix src, Type dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.Equals(typeof(double)))
            {
                return(src.DoubleValue);
            }
            else if (dstType.Equals(typeof(sbyte)))
            {
                return((sbyte)src.Resize(8, 0).SignedValue.LongValue);
            }
            else if (dstType.Equals(typeof(byte)))
            {
                return((byte)src.UFixValue.Resize(8, 0).UnsignedValue.ULongValue);
            }
            else if (dstType.Equals(typeof(short)))
            {
                return((short)src.Resize(16, 0).SignedValue.LongValue);
            }
            else if (dstType.Equals(typeof(ushort)))
            {
                return((byte)src.UFixValue.Resize(16, 0).UnsignedValue.ULongValue);
            }
            else if (dstType.Equals(typeof(int)))
            {
                return((int)src.Resize(32, 0).SignedValue.LongValue);
            }
            else if (dstType.Equals(typeof(uint)))
            {
                return((uint)src.UFixValue.Resize(32, 0).UnsignedValue.ULongValue);
            }
            else if (dstType.Equals(typeof(long)))
            {
                return(src.Resize(64, 0).SignedValue.LongValue);
            }
            else if (dstType.Equals(typeof(ulong)))
            {
                return(src.UFixValue.Resize(64, 0).UnsignedValue.ULongValue);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 30
0
        private static IEnumerable <XILSInstr> Rewrite_Sin_ScSinCos_fixpt(TypeDescriptor joker, TypeDescriptor rtype, InstructionDependency[] preds)
        {
            var iset    = DefaultInstructionSet.Instance;
            var fmt     = joker.GetFixFormat();
            var rfmt    = rtype.GetFixFormat();
            int pifw    = fmt.FracWidth;
            var pitype  = SFix.MakeType(0, pifw);
            int muliw   = fmt.IntWidth;
            var multype = SFix.MakeType(muliw, fmt.FracWidth + pifw);
            int fw      = Math.Max(5, rfmt.FracWidth + 1); // Xilinx Cordic needs at least 8 input bits

            fw = Math.Min(45, fw);                         // Xilinx Cordic likes at most 48 input bits
            var cuttype = SFix.MakeType(3, fw);
            var modtype = SFix.MakeType(3, fw);            // Actually, 1 integer bit less is required. However, Xilinx Cordic needs the additional bit.
            int fwr     = Math.Max(6, rfmt.FracWidth);     // Xilinx Cordic needs at least 8 output bits (?)

            fwr = Math.Min(46, fwr);                       // Xilinx Cordic likes at most 48 output bits (?)
            var sintype = SFix.MakeType(2, fwr);

            if (muliw <= 1)
            {
                return(new XILSInstr[]
                {
                    iset.LdConst(SFix.FromDouble(1.0 / Math.PI, 0, pifw)).CreateStk(preds, 0, pitype),
                    iset.Mul().CreateStk(2, joker, pitype, multype),
                    iset.Convert().CreateStk(1, multype, modtype),
                    iset.ScSinCos().CreateStk(1, modtype, sintype, sintype),
                    iset.Swap().CreateStk(2, sintype, sintype, sintype, sintype),
                    iset.Pop().CreateStk(1, sintype)
                });
            }
            else
            {
                return(new XILSInstr[]
                {
                    iset.LdConst(SFix.FromDouble(1.0 / Math.PI, 0, pifw)).CreateStk(preds, 0, pitype),
                    iset.Mul().CreateStk(2, joker, pitype, multype),
                    iset.Convert().CreateStk(1, multype, cuttype),
                    iset.Mod2().CreateStk(1, cuttype, modtype),
                    iset.ScSinCos().CreateStk(1, modtype, sintype, sintype),
                    iset.Swap().CreateStk(2, sintype, sintype, sintype, sintype),
                    iset.Pop().CreateStk(1, sintype)
                });
            }
        }
Esempio n. 31
0
        public static Tuple <SFix, SFix> ScSinCos(SFix value, int resultFracBits)
        {
            Contract.Requires <ArgumentOutOfRangeException>(value.DoubleValue >= -1.0, "value");
            Contract.Requires <ArgumentOutOfRangeException>(value.DoubleValue <= 1.0, "value");
            Contract.Requires <ArgumentOutOfRangeException>(resultFracBits >= 0, "resultFracBits");

            var result = Tuple.Create(
                SFix.FromDouble(
                    Math.Cos(Math.PI * value.DoubleValue),
                    2,
                    resultFracBits),
                SFix.FromDouble(
                    Math.Sin(Math.PI * value.DoubleValue),
                    2,
                    resultFracBits));

            return(result);
        }
Esempio n. 32
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes
        /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertDouble(double src, TypeDescriptor dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(SFix)))
            {
                var fmt = SFix.GetFormat(dstType);
                return(SFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth));
            }
            else if (dstType.CILType.Equals(typeof(UFix)))
            {
                var fmt = UFix.GetFormat(dstType);
                return(UFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 33
0
        private async void Computation()
        {
            await Tick;

            while (true)
            {
                ProgramFlow.DoNotUnroll();
                ProgramFlow.IOBarrier();
                Rdy.Next = '0';
                var sincos = MathExt.ScSinCos(SFix.FromSigned(X.Cur.SignedValue, _xFracWidth), _yFracWidth);
                Cos.Next = sincos.Item1.SLVValue;
                Sin.Next = sincos.Item2.SLVValue;
                await 12.Ticks();
                ProgramFlow.IOBarrier();
                Rdy.Next = '1';
                ProgramFlow.IOBarrier();
                await Tick;
            }
        }
Esempio n. 34
0
        private async void DivideProcess()
        {
            _rdy = true;
            while (true)
            {
                ProgramFlow.DoNotUnroll();

                while (!_nxt)
                {
                    ProgramFlow.DoNotUnroll();
                    await Tick;
                }

                _rdy = false;
                ProgramFlow.Barrier();
                _quotient = _dividend / _divisor;
                ProgramFlow.Barrier();
                await 10.Ticks();
                _rdy = true;
            }
        }
Esempio n. 35
0
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        /// <param name="xIntWidth">integer bits of operand</param>
        /// <param name="xFracWidth">fractional bits of operand</param>
        /// <param name="yIntWidth">integer bits of result</param>
        /// <param name="yFracWidth">fractional bits of result</param>
        /// <param name="pipeStages">desired computation-only latency</param>
        /// <param name="data">data table</param>
        public LERP11Core(int xIntWidth, int xFracWidth, int yIntWidth, int yFracWidth, int pipeStages,
            SFix[] data)
        {
            Contract.Requires<ArgumentOutOfRangeException>(xIntWidth > 0, "xIntWidth must be positive.");
            Contract.Requires<ArgumentOutOfRangeException>(xFracWidth >= 0, "xFracWidth must be non-negative.");
            Contract.Requires<ArgumentOutOfRangeException>(yIntWidth + yFracWidth > 0, "total bit-width of result must be positive");
            Contract.Requires<ArgumentOutOfRangeException>(pipeStages >= 0, "pipeStages must be non-negative.");
            Contract.Requires<ArgumentOutOfRangeException>(xFracWidth > 0 || pipeStages == 0, "xFracWidth == 0 is a degenerate case (lookup-only). No additional pipeline stages allowed.");
            Contract.Requires<ArgumentNullException>(data != null, "data");

            PipeStages = pipeStages;
            XIntWidth = xIntWidth;
            XFracWidth = xFracWidth;
            YIntWidth = yIntWidth;
            YFracWidth = yFracWidth;
            DIntWidth = data[0].Format.IntWidth;
            DFracWidth = data[0].Format.FracWidth;

            _x = new Signal<UFix>()
            {
                InitialValue = UFix.FromDouble(0.0, xIntWidth, xFracWidth)
            };
            _y = new Signal<SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, yIntWidth, yFracWidth)
            };
            AddrWidth = MathExt.CeilPow2(data.Length);
            _unitAddr = new Signal<Unsigned>()
            {
                InitialValue = Unsigned.FromUInt(0, AddrWidth)
            };
            _memContent = new VSignal<SFix>(data.Length, _ => new Signal<SFix>() { InitialValue = data[_] });

            _lerpUnit = new LERPUnit(xIntWidth, xFracWidth, yIntWidth, yFracWidth, pipeStages);
            Bind(() =>
            {
                _lerpUnit.Clk = Clk;
                _lerpUnit.X = _x;
                _lerpUnit.Y = _y;
                _lerpUnit.Addr = _unitAddr;
                _lerpUnit.Data = _unitData;
            });
        }
Esempio n. 36
0
        static void PrintMatrix(SFix[,] A)
        {
            int n = A.GetLength(0);
            for (int i = 0; i < n; i++)
            {
                if (i > 0)
                    Console.WriteLine();

                for (int j = 0; j < n; j++)
                {
                    if (j > 0)
                        Console.Write(" ");
                    Console.Write(A[i, j].ToString(10, 2));
                }
            }
        }
Esempio n. 37
0
        public static void RunTest()
        {
            FixedPointSettings.GlobalDefaultRadix = 10;
            FixedPointSettings.GlobalOverflowMode = EOverflowMode.Fail;

            SFix s1 = SFix.FromDouble(1.0, 2, 2);
            SFix s2 = SFix.FromDouble(-0.75, 2, 2);
            SFix s3 = s1 / s2;

            Random rnd = new Random();
            int n = 10;
            int iw = 14;
            int fw = 14;
            double eps = Math.Pow(2.0, -fw);
            SFix[,] A = new SFix[n, n];
            double[,] Ad = new double[n, n];
            SFix[] b = new SFix[n];
            double[] bd = new double[n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double a = 2.0 * rnd.NextDouble() - 1.0;
                    Ad[i, j] = a;
                }
            }
            //Ad = new double[,] { { 4, -2, 1 }, { -3, -1, 4 }, { 1, -1, 3 } };
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double a = Ad[i, j];
                    SFix c = SFix.FromDouble(a, iw, fw);
                    string cs = c.ToString();
                    double ar = c.DoubleValue;
                    double d = a - ar;
                    double da = Math.Abs(d);
                    Debug.Assert(da < eps);
                    A[i, j] = c;
                    Ad[i, j] = a;
                }
                double bi = 2.0 * rnd.NextDouble() - 1.0;
                b[i] = SFix.FromDouble(bi, 3, 33);
                bd[i] = bi;
            }
            SFix[,] Ac = (SFix[,])A.Clone();
            Console.WriteLine("Original matrix:");
            PrintMatrix(A);
            Console.WriteLine();
            ComputeLU(A, iw, fw);
            Console.WriteLine("LU:");
            PrintMatrix(A);
            Console.WriteLine();

            SFix[] x = new SFix[n];
            SFix[] y = new SFix[n];
            SubstituteLU(A, b, y, x);

            Console.WriteLine("Precisions:");
            for (int i = 0; i < n; i++)
            {
                SFix bc = Ac[i, 0] * x[0];
                for (int j = 1; j < n; j++)
                {
                    bc += Ac[i, j] * x[j];
                }
                SFix d = bc - b[i];
                Console.Write("b[" + i + "] = " + b[i].ToString(10, 2));
                Console.Write(" / " + bc.ToString(10, 2));
                Console.WriteLine(" / d = " + d.ToString(10, 2));
            }
        }
Esempio n. 38
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes
        /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertSFix(SFix src, TypeDescriptor dstType)
        {
            Contract.Requires<ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(SFix)))
                return src.Resize(SFix.GetFormat(dstType).IntWidth, SFix.GetFormat(dstType).FracWidth);
            else if (dstType.CILType.Equals(typeof(Signed)))
                return src.SignedValue.Resize(SFix.GetFormat(dstType).IntWidth);
            else if (dstType.CILType.Equals(typeof(StdLogicVector)))
                return src.SLVValue[StdLogicVector.GetLength(dstType) - 1, 0];
            else
                return ConvertSFix(src, dstType.CILType);
        }
Esempio n. 39
0
        /// <summary>
        /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow.
        /// </summary>
        /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception>
        /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception>
        public static object ConvertSFix(SFix src, Type dstType)
        {
            Contract.Requires<ArgumentNullException>(dstType != null, "dstType");

            if (dstType.Equals(typeof(double)))
                return src.DoubleValue;
            else if (dstType.Equals(typeof(sbyte)))
                return (sbyte)src.Resize(8, 0).SignedValue.LongValue;
            else if (dstType.Equals(typeof(byte)))
                return (byte)src.UFixValue.Resize(8, 0).UnsignedValue.ULongValue;
            else if (dstType.Equals(typeof(short)))
                return (short)src.Resize(16, 0).SignedValue.LongValue;
            else if (dstType.Equals(typeof(ushort)))
                return (byte)src.UFixValue.Resize(16, 0).UnsignedValue.ULongValue;
            else if (dstType.Equals(typeof(int)))
                return (int)src.Resize(32, 0).SignedValue.LongValue;
            else if (dstType.Equals(typeof(uint)))
                return (uint)src.UFixValue.Resize(32, 0).UnsignedValue.ULongValue;
            else if (dstType.Equals(typeof(long)))
                return src.Resize(64, 0).SignedValue.LongValue;
            else if (dstType.Equals(typeof(ulong)))
                return src.UFixValue.Resize(64, 0).UnsignedValue.ULongValue;
            else
                throw new NotImplementedException();
        }