예제 #1
0
파일: LERP.cs 프로젝트: cephdon/systemsharp
        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;
        }
예제 #2
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 ConvertUnsigned(Unsigned src, Type dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.Equals(typeof(double)))
            {
                return(UFix.FromUnsigned(src, 0).DoubleValue);
            }
            else
            {
                return(ConvertValue(src.ULongValue, dstType));
            }
        }
예제 #3
0
파일: LERP.cs 프로젝트: cephdon/systemsharp
        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();
            }
        }
예제 #4
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 ConvertUnsigned(Unsigned src, TypeDescriptor dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(Unsigned)))
            {
                return(src.Resize(UFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(UFix)))
            {
                return(UFix.FromUnsigned(src.Resize(UFix.GetFormat(dstType).TotalWidth), UFix.GetFormat(dstType).FracWidth));
            }
            else
            {
                return(ConvertUnsigned(src, dstType.CILType));
            }
        }
예제 #5
0
        private async void Computation()
        {
            await Tick;

            while (true)
            {
                ProgramFlow.DoNotUnroll();
                ProgramFlow.IOBarrier();
                Rdy.Next   = '0';
                Sqrt1.Next = MathExt.Sqrt(UFix.FromUnsigned(X1.Cur.UnsignedValue, _fracWidth)).SLVValue;
                Sqrt2.Next = MathExt.Sqrt(UFix.FromUnsigned(X2.Cur.UnsignedValue, _fracWidth)).SLVValue;
                await NTicks(63);

                ProgramFlow.IOBarrier();
                Rdy.Next = '1';
                ProgramFlow.IOBarrier();
                await Tick;
            }
        }
예제 #6
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 ConvertULong(ulong src, TypeDescriptor dstType)
        {
            Contract.Requires <ArgumentNullException>(dstType != null, "dstType");

            if (dstType.CILType.Equals(typeof(Unsigned)))
            {
                return(Unsigned.FromULong(src, UFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(Signed)))
            {
                return(Signed.FromBigInt(new System.Numerics.BigInteger(src), UFix.GetFormat(dstType).IntWidth));
            }
            else if (dstType.CILType.Equals(typeof(UFix)))
            {
                return(UFix.FromUnsigned(Unsigned.FromULong(src, UFix.GetFormat(dstType).IntWidth), UFix.GetFormat(dstType).FracWidth));
            }
            else
            {
                return(ConvertULong(src, dstType.CILType));
            }
        }
예제 #7
0
 private async void StimulateAndTest()
 {
     for (double i = 0.01; i < 100.0; i *= 2.0)
     {
         _x1.Next = UFix.FromDouble(i, 8, 8).SLVValue;
         _x2.Next = UFix.FromDouble(i, 9, 8).SLVValue;
         while (_rdy.Cur != '0')
         {
             await _rdy;
         }
         while (_rdy.Cur != '1')
         {
             await _rdy;
         }
         var x1    = UFix.FromUnsigned(_x1.Cur.UnsignedValue, 8);
         var sqrt1 = UFix.FromUnsigned(_sqrt1.Cur.UnsignedValue, 12);
         Console.WriteLine("X1 = " + x1.DoubleValue + ", Sqrt = " + sqrt1.DoubleValue + ", Sqrt^2 = " + (sqrt1 * sqrt1).DoubleValue);
         var x2    = UFix.FromUnsigned(_x2.Cur.UnsignedValue, 8);
         var sqrt2 = UFix.FromUnsigned(_sqrt2.Cur.UnsignedValue, 12);
         Console.WriteLine("X2 = " + x1.DoubleValue + ", Sqrt = " + sqrt2.DoubleValue + ", Sqrt^2 = " + (sqrt2 * sqrt2).DoubleValue);
     }
 }
예제 #8
0
파일: LERP.cs 프로젝트: cephdon/systemsharp
        /// <summary>
        /// Constructs a new instance
        /// </summary>
        /// <param name="lutWidth">resolution of data table</param>
        /// <param name="xFracWidth">fractional width of operand</param>
        /// <param name="yFracWidth">fractional width of result</param>
        /// <param name="pipeStages">additional pipeline stages for interpolation computation</param>
        public SinCosLUTCore(int lutWidth, int xFracWidth, int yFracWidth, int pipeStages)
        {
            PipeStages = pipeStages;
            XIntWidth  = 2;
            XFracWidth = xFracWidth;
            YIntWidth  = 2;
            YFracWidth = yFracWidth;
            DIntWidth  = 2;
            DFracWidth = yFracWidth;
            LUTWidth   = lutWidth;

            _x = new Signal <UFix>()
            {
                InitialValue = UFix.FromDouble(0.0, LUTWidth + 1, XFracWidth - LUTWidth - 1)
            };
            _xq = new Signal <UFix>()
            {
                InitialValue = UFix.FromDouble(0.0, LUTWidth + 1, XFracWidth - LUTWidth - 1)
            };
            _sinRaw = new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth)
            };
            _cosRaw = new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth)
            };
            _sinIn = new SLVSignal(YIntWidth + YFracWidth)
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue
            };
            _cosIn = new SLVSignal(YIntWidth + YFracWidth)
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue
            };
            _sinOut = new SLVSignal(YIntWidth + YFracWidth)
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue
            };
            _cosOut = new SLVSignal(YIntWidth + YFracWidth)
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue
            };
            AddrWidth = lutWidth + 1;
            _sinAddr  = new Signal <Unsigned>()
            {
                InitialValue = Unsigned.FromUInt(0, AddrWidth)
            };
            _cosAddr = new Signal <Unsigned>()
            {
                InitialValue = Unsigned.FromUInt(0, AddrWidth)
            };
            _sinData = new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth)
            };
            _cosData = new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth)
            };
            _sinLUT = new VSignal <SFix>((1 << lutWidth) + 2, _ => new Signal <SFix>()
            {
                InitialValue = SFix.FromDouble(Math.Sin(Math.PI * 0.5 * _ / (double)(1 << lutWidth)), 2, yFracWidth)
            });
            _sinFlipSignIn = new SLVSignal(1)
            {
                InitialValue = "0"
            };
            _cosFlipSignIn = new SLVSignal(1)
            {
                InitialValue = "0"
            };
            _sinFlipSignOut = new SLVSignal(1)
            {
                InitialValue = "0"
            };
            _cosFlipSignOut = new SLVSignal(1)
            {
                InitialValue = "0"
            };

            _mirror  = UFix.FromUnsigned(Unsigned.One.Resize(XFracWidth + 2) << (xFracWidth + 1), xFracWidth - LUTWidth);
            _mirror2 = UFix.FromUnsigned(Unsigned.One.Resize(XFracWidth + 2) << xFracWidth, xFracWidth - LUTWidth);

            _sinPipe = new RegPipe(pipeStages, YIntWidth + YFracWidth);
            Bind(() => {
                _sinPipe.Clk  = Clk;
                _sinPipe.Din  = _sinIn;
                _sinPipe.Dout = _sinOut;
            });

            _cosPipe = new RegPipe(pipeStages, YIntWidth + YFracWidth);
            Bind(() => {
                _cosPipe.Clk  = Clk;
                _cosPipe.Din  = _cosIn;
                _cosPipe.Dout = _cosOut;
            });

            _sinFlipSignPipe = new RegPipe(2, 1);
            Bind(() => {
                _sinFlipSignPipe.Clk  = Clk;
                _sinFlipSignPipe.Din  = _sinFlipSignIn;
                _sinFlipSignPipe.Dout = _sinFlipSignOut;
            });

            _cosFlipSignPipe = new RegPipe(2, 1);
            Bind(() => {
                _cosFlipSignPipe.Clk  = Clk;
                _cosFlipSignPipe.Din  = _cosFlipSignIn;
                _cosFlipSignPipe.Dout = _cosFlipSignOut;
            });

            _sinUnit = new LERPUnit(lutWidth + 1, xFracWidth - 1 - lutWidth, YIntWidth, yFracWidth, 0);
            Bind(() =>
            {
                _sinUnit.Clk  = Clk;
                _sinUnit.X    = _x;
                _sinUnit.Y    = _sinRaw;
                _sinUnit.Addr = _sinAddr;
                _sinUnit.Data = _sinData;
            });

            _cosUnit = new LERPUnit(lutWidth + 1, xFracWidth - 1 - lutWidth, YIntWidth, yFracWidth, 0);
            Bind(() =>
            {
                _cosUnit.Clk  = Clk;
                _cosUnit.X    = _xq;
                _cosUnit.Y    = _cosRaw;
                _cosUnit.Addr = _cosAddr;
                _cosUnit.Data = _cosData;
            });

            TASite = new TransactionSite(this);
        }
예제 #9
0
 public static UFix Abs(SFix value)
 {
     return(UFix.FromUnsigned(
                Abs(value.SignedValue),
                value.Format.FracWidth));
 }
예제 #10
0
        private void HandleDiv(XILSInstr i)
        {
            var preds       = i.Preds;
            var fmtDividend = i.OperandTypes[0].GetFixFormat();
            var fmtDivisor  = i.OperandTypes[1].GetFixFormat();
            var fmtQuotient = i.ResultTypes[0].GetFixFormat();

            if (fmtDividend == null ||
                fmtDivisor == null ||
                fmtQuotient == null)
            {
                ProcessDefault(i);
                return;
            }

            if (!fmtDivisor.IsSigned)
            {
                // Xilinx divider wants it signed
                var signedType = SFix.MakeType(fmtDivisor.IntWidth + 1, fmtDivisor.FracWidth);
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, i.OperandTypes[1], signedType));
                var newi = i.Command.CreateStk(2, i.OperandTypes[0], signedType, i.ResultTypes[0]);
                HandleDiv(newi);
                return;
            }

            if (!fmtDividend.IsSigned)
            {
                // Xilinx divider wants it signed
                var signedType = SFix.MakeType(fmtDividend.IntWidth + 1, fmtDividend.FracWidth);
                Emit(DefaultInstructionSet.Instance.Swap().CreateStk(preds, 2,
                                                                     i.OperandTypes[0], i.OperandTypes[1],
                                                                     i.OperandTypes[1], i.OperandTypes[0]));
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, i.OperandTypes[0], signedType));
                Emit(DefaultInstructionSet.Instance.Swap().CreateStk(2,
                                                                     i.OperandTypes[1], signedType,
                                                                     signedType, i.OperandTypes[1]));
                var newi = i.Command.CreateStk(2, signedType, i.OperandTypes[1], i.ResultTypes[0]);
                HandleDiv(newi);
                return;
            }

            if (!fmtQuotient.IsSigned)
            {
                // Xilinx divider wants it signed
                var signedType = SFix.MakeType(fmtQuotient.IntWidth + 1, fmtQuotient.FracWidth);
                var newi       = i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], signedType);
                HandleDiv(newi);
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, signedType, i.ResultTypes[0]));
                return;
            }

            if (fmtDividend.TotalWidth < 4 ||
                fmtDivisor.TotalWidth < 4)
            {
                // Xilinx fixed point divider doesn't like divisions of less than 4 bits
                throw new NotImplementedException("Encountered fixed point division with less than 4 bits of either dividend or divisor. This is not supported, please adjust the division!");

                /*Emit(DefaultInstructionSet.Instance.Swap().CreateStk(preds, 2,
                 *  i.OperandTypes[0], i.OperandTypes[1],
                 *  i.OperandTypes[1], i.OperandTypes[0]));
                 * int delta = 4 - fmtDividend.TotalWidth - 4;
                 * var newDividendType = fmtDividend.IsSigned ?
                 *  SFix.MakeType(
                 * Emit(i.Command.CreateStk(1, i.OperandTypes[1]*/
            }

            int    hwQuotientTotalWidth = fmtDividend.TotalWidth;
            int    hwQuotientFracWidth  = fmtDividend.FracWidth - fmtDivisor.FracWidth;
            object hwQuotSample         = fmtDividend.IsSigned ?
                                          (object)SFix.FromDouble(0.0, hwQuotientTotalWidth - hwQuotientFracWidth, hwQuotientFracWidth) :
                                          (object)UFix.FromDouble(0.0, hwQuotientTotalWidth - hwQuotientFracWidth, hwQuotientFracWidth);
            var            hwQuotType = TypeDescriptor.GetTypeOf(hwQuotSample);
            TypeDescriptor hwQuotAndFracType;

            if (hwQuotientFracWidth >= fmtQuotient.FracWidth)
            {
                Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], hwQuotType));
                hwQuotAndFracType = hwQuotType;
            }
            else
            {
                int fracWidth = fmtQuotient.FracWidth - hwQuotientFracWidth;
                if (fracWidth > 54)
                {
                    // Xilinx divider doesn't like fractional width > 54
                    throw new NotImplementedException("Encountered fixed point division with more than 54 bits of fractional width. This is not supported, please adjust the division!");
                }
                var hwFracSample = UFix.FromDouble(0.0, -hwQuotientFracWidth, fmtQuotient.FracWidth);
                var hwFracType   = TypeDescriptor.GetTypeOf(hwFracSample);
                Emit(DefaultInstructionSet.Instance.DivQF().CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], hwQuotType, hwFracType));
                var hwQuotSLV     = Marshal.SerializeForHW(hwQuotSample);
                var hwFracSLV     = Marshal.SerializeForHW(hwFracSample);
                var hwQuotSLVType = TypeDescriptor.GetTypeOf(hwQuotSLV);
                var hwFracSLVType = TypeDescriptor.GetTypeOf(hwFracSLV);
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, hwFracType, hwFracSLVType));
                Emit(DefaultInstructionSet.Instance.Dig(1).CreateStk(2, hwQuotType, hwFracSLVType, hwFracSLVType, hwQuotType));
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, hwQuotType, hwQuotSLVType));
                Emit(DefaultInstructionSet.Instance.Dig(1).CreateStk(2, hwFracSLVType, hwQuotSLVType, hwQuotSLVType, hwFracSLVType));
                var hwConcSLV     = hwQuotSLV.Concat(hwFracSLV);
                var hwConcSLVType = TypeDescriptor.GetTypeOf(hwConcSLV);
                Emit(DefaultInstructionSet.Instance.Concat().CreateStk(2, hwQuotSLVType, hwFracSLVType, hwConcSLVType));
                object hwConc;
                if (fmtDividend.IsSigned)
                {
                    hwConc = SFix.FromSigned(hwConcSLV.SignedValue, fmtQuotient.FracWidth);
                }
                else
                {
                    hwConc = UFix.FromUnsigned(hwConcSLV.UnsignedValue, fmtQuotient.FracWidth);
                }
                var hwConcType = TypeDescriptor.GetTypeOf(hwConc);
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, hwConcSLVType, hwConcType));
                hwQuotAndFracType = hwConcType;
            }
            if (!hwQuotAndFracType.Equals(i.ResultTypes[0]))
            {
                Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, hwQuotAndFracType, i.ResultTypes[0]));
            }
        }