Esempio n. 1
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. 2
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. 3
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. 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 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. 5
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. 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 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. 7
0
        /// <summary>
        /// Returns a sequence of adminissible result types, given instruction operand types.
        /// </summary>
        /// <param name="instr">XIL instruction</param>
        /// <param name="operandTypes">operand types</param>
        /// <returns>admissible result types</returns>
        public static IEnumerable <TypeDescriptor> GetDefaultResultTypes(this XILInstr instr, TypeDescriptor[] operandTypes)
        {
            switch (instr.Name)
            {
            case InstructionCodes.Abs:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)) ||
                    operandTypes[0].CILType.Equals(typeof(int)) ||
                    operandTypes[0].CILType.Equals(typeof(long)) ||
                    operandTypes[0].CILType.Equals(typeof(sbyte)) ||
                    operandTypes[0].CILType.Equals(typeof(short)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(typeof(double));
                }
                else if (operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt     = SFix.GetFormat(operandTypes[0]);
                    var ssample = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth);
                    yield return(TypeDescriptor.GetTypeOf(ssample));

                    var usample = UFix.FromDouble(0.0, fmt.IntWidth, fmt.FracWidth);
                    yield return(TypeDescriptor.GetTypeOf(usample));
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)))
                {
                    yield return(operandTypes[0]);
                }
                else
                {
                    throw new NotSupportedException("Operand type not supported");
                }
                break;

            case InstructionCodes.Add:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 + o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.And:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 & o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Barrier:
            case InstructionCodes.BranchIfFalse:
            case InstructionCodes.BranchIfTrue:
                yield break;

            case InstructionCodes.Ceil:
            case InstructionCodes.Floor:
            case InstructionCodes.SinCos:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.Cos:
            case InstructionCodes.Sin:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)) ||
                         operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = operandTypes[0].GetFixFormat();
                    // computation works for at most 26 fractional bits
                    double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth));
                    double yinc = 1.0 - Math.Cos(xinc);
                    int    fw   = -MathExt.FloorLog2(yinc);
                    // Xilinx Cordic doesn't like more than 48 result bits
                    if (fw > 48)
                    {
                        fw = 48;
                    }
                    while (fw >= 0)
                    {
                        yield return(SFix.MakeType(2, fw));

                        --fw;
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.ScSin:
            case InstructionCodes.ScCos:
            case InstructionCodes.ScSinCos:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)) ||
                         operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = operandTypes[0].GetFixFormat();
                    // computation works for at most 26 fractional bits
                    double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth));
                    double yinc = 1.0 - Math.Cos(xinc);
                    int    fw   = -MathExt.FloorLog2(yinc);
                    // Xilinx Cordic doesn't like more than 48 result bits
                    if (fw > 48)
                    {
                        fw = 48;
                    }
                    while (fw >= 0)
                    {
                        yield return(SFix.MakeType(2, fw));

                        --fw;
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.Sqrt:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)))
                {
                    var fmt = UFix.GetFormat(operandTypes[0]);
                    int iw  = (fmt.IntWidth + 1) / 2;
                    yield return(UFix.MakeType(iw, fmt.TotalWidth - iw));
                }
                else if (operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = SFix.GetFormat(operandTypes[0]);
                    int iw  = fmt.IntWidth / 2;
                    yield return(UFix.MakeType(iw, fmt.TotalWidth - iw - 1));
                }
                else if (operandTypes[0].CILType.Equals(typeof(Unsigned)))
                {
                    var fmt = UFix.GetFormat(operandTypes[0]);
                    int iw  = (fmt.IntWidth + 1) / 2;
                    yield return(Unsigned.MakeType(iw));
                }
                else if (operandTypes[0].CILType.Equals(typeof(Signed)))
                {
                    var fmt = SFix.GetFormat(operandTypes[0]);
                    int iw  = fmt.IntWidth / 2;
                    yield return(Unsigned.MakeType(iw));
                }
                else
                {
                    throw new NotImplementedException();
                }
                break;

            case InstructionCodes.Cmp:
                throw new NotImplementedException();

            case InstructionCodes.Concat:
            {
                var v1 = (StdLogicVector)operandTypes[0].GetSampleInstance();
                var v2 = (StdLogicVector)operandTypes[1].GetSampleInstance();
                var c  = v1.Concat(v2);
                yield return(TypeDescriptor.GetTypeOf(c));
            }
            break;

            case InstructionCodes.Convert:
                throw new NotImplementedException();

            case InstructionCodes.Dig:
            case InstructionCodes.Dup:
            case InstructionCodes.Swap:
                throw new NotSupportedException();

            case InstructionCodes.Div:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero);
                object  r  = o1 / o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.ExitMarshal:
            case InstructionCodes.Goto:
            case InstructionCodes.Nop:
            case InstructionCodes.Pop:
            case InstructionCodes.Return:
            case InstructionCodes.StelemFixA:
            case InstructionCodes.StelemFixAFixI:
            case InstructionCodes.StoreVar:
            case InstructionCodes.WrMem:
            case InstructionCodes.WrMemFix:
            case InstructionCodes.WrPort:
                yield break;

            case InstructionCodes.Mod2:
            {
                var fmt = operandTypes[0].GetFixFormat();
                if (fmt == null)
                {
                    throw new NotSupportedException("mod2 is only supported for fixed-point types");
                }

                for (int iw = 2; iw <= fmt.IntWidth; iw++)
                {
                    yield return(new FixFormat(fmt.IsSigned, iw, fmt.FracWidth).ToType());
                }
            }
            break;

            case InstructionCodes.DivQF:
            case InstructionCodes.ExtendSign:
            case InstructionCodes.Ld0:
            case InstructionCodes.LdelemFixA:
            case InstructionCodes.LdelemFixAFixI:
            case InstructionCodes.LdMemBase:
            case InstructionCodes.LShift:
            case InstructionCodes.RdMem:
            case InstructionCodes.RdMemFix:
            case InstructionCodes.RShift:
            case InstructionCodes.Sign:
            case InstructionCodes.SliceFixI:
                throw new NotImplementedException();

            case InstructionCodes.IsEq:
            case InstructionCodes.IsGt:
            case InstructionCodes.IsGte:
            case InstructionCodes.IsLt:
            case InstructionCodes.IsLte:
            case InstructionCodes.IsNEq:
                yield return(typeof(bool));

                break;

            case InstructionCodes.LdConst:
                yield return(TypeDescriptor.GetTypeOf(instr.Operand));

                break;

            case InstructionCodes.LoadVar:
            {
                var lit = (IStorableLiteral)instr.Operand;
                yield return(lit.Type);
            }
            break;

            case InstructionCodes.Max:
            case InstructionCodes.Min:
                yield return(operandTypes[0]);

                break;

            case InstructionCodes.Mul:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 * o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Neg:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                object  r  = -o1;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Not:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                object  r  = !o1;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Or:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 | o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.RdPort:
            {
                var port = (ISignalOrPortDescriptor)instr.Operand;
                yield return(port.ElementType);
            }
            break;

            case InstructionCodes.Rem:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero);
                object  r  = o1 % o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Rempow2:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                int     n  = (int)instr.Operand;
                object  r  = MathExt.Rempow2((dynamic)o1, n);
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Select:
                yield return(operandTypes[1]);

                break;

            case InstructionCodes.Slice:
                yield return(typeof(StdLogicVector));

                break;

            case InstructionCodes.Sub:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 - o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Xor:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 ^ o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Returns a type which is able to represent either of two given types without loss of precision
        /// </summary>
        /// <param name="td1">first given type</param>
        /// <param name="td2">second given type</param>
        /// <returns></returns>
        private static TypeDescriptor GetCommonType(TypeDescriptor td1, TypeDescriptor td2)
        {
            if (td1.Equals(td2))
            {
                return(td1);
            }

            if (IsSFix(td1) && IsUFix(td2))
            {
                var fmt1 = SFix.GetFormat(td1);
                var fmt2 = UFix.GetFormat(td2);
                return(SFix.MakeType(
                           Math.Max(fmt1.IntWidth, fmt2.IntWidth + 1),
                           Math.Max(fmt1.FracWidth, fmt2.FracWidth)));
            }
            else if (IsUFix(td1) && IsSFix(td2))
            {
                return(GetCommonType(td2, td1));
            }
            else if (IsSFix(td1) && IsSFix(td2))
            {
                var fmt1 = SFix.GetFormat(td1);
                var fmt2 = SFix.GetFormat(td2);
                return(SFix.MakeType(
                           Math.Max(fmt1.IntWidth, fmt2.IntWidth),
                           Math.Max(fmt1.FracWidth, fmt2.FracWidth)));
            }
            else if (IsUFix(td1) && IsUFix(td2))
            {
                var fmt1 = UFix.GetFormat(td1);
                var fmt2 = UFix.GetFormat(td2);
                return(UFix.MakeType(
                           Math.Max(fmt1.IntWidth, fmt2.IntWidth),
                           Math.Max(fmt1.FracWidth, fmt2.FracWidth)));
            }
            else if (IsSigned(td1))
            {
                var fmt  = SFix.GetFormat(td1);
                var td1x = SFix.MakeType(fmt.IntWidth, fmt.FracWidth);
                return(GetCommonType(td1x, td2));
            }
            else if (IsSigned(td2))
            {
                return(GetCommonType(td2, td1));
            }
            else if (IsUnsigned(td1))
            {
                var fmt  = UFix.GetFormat(td1);
                var td1x = UFix.MakeType(fmt.IntWidth, fmt.FracWidth);
                return(GetCommonType(td1x, td2));
            }
            else if (IsUnsigned(td2))
            {
                return(GetCommonType(td2, td1));
            }
            else
            {
                throw new NotSupportedException(
                          "Cannot determine common type between " +
                          td1.ToString() + " and " + td2.ToString());
            }
        }
Esempio n. 9
0
        private void ProcessAddSub(XILSInstr i)
        {
            var preds = RemapPreds(i.Preds);

            if (IsFixed(i.OperandTypes[0]) &&
                IsFixed(i.OperandTypes[1]))
            {
                if (IsSFix(i.OperandTypes[0]) &&
                    IsUFix(i.OperandTypes[1]))
                {
                    var sfixt = MakeUFixSFix(i.OperandTypes[1]);
                    Convert(preds, i.OperandTypes[1], sfixt);
                    var inew = i.Command.CreateStk(2, i.OperandTypes[0], sfixt, i.ResultTypes[0]);
                    ProcessAddSub(inew);
                }
                else if (IsUFix(i.OperandTypes[0]) &&
                         IsSFix(i.OperandTypes[1]))
                {
                    var sfixt = MakeUFixSFix(i.OperandTypes[0]);
                    Swap(preds);
                    Convert(i.OperandTypes[0], sfixt);
                    Swap();
                    var inew = i.Command.CreateStk(2, sfixt, i.OperandTypes[1], i.ResultTypes[0]);
                    ProcessAddSub(inew);
                }
                else if (IsSFix(i.OperandTypes[0]) &&
                         IsSFix(i.OperandTypes[1]))
                {
                    var fmt0 = SFix.GetFormat(i.OperandTypes[0]);
                    var fmt1 = SFix.GetFormat(i.OperandTypes[1]);
                    int iw   = Math.Max(fmt0.IntWidth, fmt1.IntWidth);
                    int fw   = Math.Max(fmt0.FracWidth, fmt1.FracWidth);
                    var smp  = SFix.FromDouble(0.0, iw, fw);
                    var to   = TypeDescriptor.GetTypeOf(smp);
                    var fmte = SFix.GetFormat(to);
                    if (!fmte.Equals(fmt1))
                    {
                        Convert(preds, i.OperandTypes[1], to);
                        var inew = i.Command.CreateStk(2, i.OperandTypes[0], to, i.ResultTypes[0]);
                        ProcessAddSub(inew);
                    }
                    else if (!fmte.Equals(fmt0))
                    {
                        Swap(preds);
                        Convert(i.OperandTypes[0], to);
                        Swap();
                        var inew = i.Command.CreateStk(2, to, i.OperandTypes[1], i.ResultTypes[0]);
                        ProcessAddSub(inew);
                    }
                    else
                    {
                        dynamic s0    = i.OperandTypes[0].GetSampleInstance();
                        dynamic s1    = i.OperandTypes[1].GetSampleInstance();
                        object  r     = s0 + s1;
                        var     rtype = TypeDescriptor.GetTypeOf(r);
                        Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype));
                        if (!rtype.Equals(i.ResultTypes[0]))
                        {
                            Convert(rtype, i.ResultTypes[0]);
                        }
                    }
                }
                else if (IsUFix(i.OperandTypes[0]) &&
                         IsUFix(i.OperandTypes[1]) &&
                         IsSFix(i.ResultTypes[0]))
                {
                    var sfixt = MakeUFixSFix(i.OperandTypes[1]);
                    Convert(preds, i.OperandTypes[1], sfixt);
                    var inew = i.Command.CreateStk(2, i.OperandTypes[0], sfixt, i.ResultTypes[0]);
                    ProcessAddSub(inew);
                }
                else if (IsUFix(i.OperandTypes[0]) &&
                         IsUFix(i.OperandTypes[1]))
                {
                    var fmt0 = UFix.GetFormat(i.OperandTypes[0]);
                    var fmt1 = UFix.GetFormat(i.OperandTypes[1]);
                    int iw   = Math.Max(fmt0.IntWidth, fmt1.IntWidth);
                    int fw   = Math.Max(fmt0.FracWidth, fmt1.FracWidth);
                    var smp  = UFix.FromDouble(0.0, iw, fw);
                    var to   = TypeDescriptor.GetTypeOf(smp);
                    var fmte = UFix.GetFormat(to);
                    if (!fmte.Equals(fmt1))
                    {
                        Convert(preds, i.OperandTypes[1], to);
                        var inew = i.Command.CreateStk(2, i.OperandTypes[0], to, i.ResultTypes[0]);
                        ProcessAddSub(inew);
                    }
                    else if (!fmte.Equals(fmt0))
                    {
                        Swap(preds);
                        Convert(preds, i.OperandTypes[0], to);
                        Swap();
                        var inew = i.Command.CreateStk(2, to, i.OperandTypes[1], i.ResultTypes[0]);
                        ProcessAddSub(inew);
                    }
                    else
                    {
                        dynamic s0    = i.OperandTypes[0].GetSampleInstance();
                        dynamic s1    = i.OperandTypes[1].GetSampleInstance();
                        object  r     = s0 + s1;
                        var     rtype = TypeDescriptor.GetTypeOf(r);
                        Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype));
                        if (!rtype.Equals(i.ResultTypes[0]))
                        {
                            Convert(rtype, i.ResultTypes[0]);
                        }
                    }
                }
                else
                {
                    Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], i.ResultTypes[0]));
                }
            }
            else if (IsFloat(i.OperandTypes[0]) && IsFloat(i.OperandTypes[1]))
            {
                dynamic s0    = i.OperandTypes[0].GetSampleInstance();
                dynamic s1    = i.OperandTypes[1].GetSampleInstance();
                object  r     = s0 + s1;
                var     rtype = TypeDescriptor.GetTypeOf(r);
                Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype));
                if (!rtype.Equals(i.ResultTypes[0]))
                {
                    Convert(rtype, i.ResultTypes[0]);
                }
            }
            else if (IsFixed(i.OperandTypes[0]) &&
                     IsFloat(i.OperandTypes[1]) &&
                     IsFixed(i.ResultTypes[0]))
            {
                Convert(preds, i.OperandTypes[1], i.OperandTypes[0]);
                var inew = i.Command.CreateStk(2, i.OperandTypes[0], i.OperandTypes[0], i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else if (IsFloat(i.OperandTypes[0]) &&
                     IsFixed(i.OperandTypes[1]) &&
                     IsFixed(i.ResultTypes[0]))
            {
                Swap(preds);
                Convert(i.OperandTypes[0], i.OperandTypes[1]);
                Swap();
                var inew = i.Command.CreateStk(2, i.OperandTypes[1], i.OperandTypes[0], i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else if (IsFixed(i.OperandTypes[0]) &&
                     IsFloat(i.OperandTypes[1]) &&
                     IsFloat(i.ResultTypes[0]))
            {
                Swap(preds);
                Convert(i.OperandTypes[0], i.OperandTypes[1]);
                Swap();
                var inew = i.Command.CreateStk(2, i.OperandTypes[1], i.OperandTypes[0], i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else if (IsFloat(i.OperandTypes[0]) &&
                     IsFixed(i.OperandTypes[1]) &&
                     IsFloat(i.ResultTypes[0]))
            {
                Convert(preds, i.OperandTypes[1], i.OperandTypes[0]);
                var inew = i.Command.CreateStk(2, i.OperandTypes[0], i.OperandTypes[0], i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else if (IsSLV(i.OperandTypes[1]))
            {
                var signedType = SFix.MakeType(StdLogicVector.GetLength(i.OperandTypes[1]), 0);
                Convert(preds, i.OperandTypes[1], signedType);
                var inew = i.Command.CreateStk(2, i.OperandTypes[0], signedType, i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else if (IsSLV(i.OperandTypes[0]))
            {
                var signedType = SFix.MakeType(StdLogicVector.GetLength(i.OperandTypes[0]), 0);
                Swap(preds);
                Convert(i.OperandTypes[0], signedType);
                Swap();
                var inew = i.Command.CreateStk(2, signedType, i.OperandTypes[1], i.ResultTypes[0]);
                ProcessAddSub(inew);
            }
            else
            {
                Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], i.ResultTypes[0]));
            }
        }
Esempio n. 10
0
 private InstructionDependency[] Convert(InstructionDependency[] preds, TypeDescriptor from, TypeDescriptor to)
 {
     if (from.Equals(to))
     {
         // nothing to do
         return(preds);
     }
     else if (IsSFix(from) && IsUFix(to))
     {
         var fromFmt = SFix.GetFormat(from);
         var toFmt   = UFix.GetFormat(to);
         int interIW = toFmt.IntWidth + 1;
         int interFW = toFmt.FracWidth;
         if (interIW != fromFmt.IntWidth ||
             interFW != fromFmt.FracWidth)
         {
             var interType = SFix.MakeType(interIW, interFW);
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType));
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to));
         }
         else
         {
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to));
         }
         return(new InstructionDependency[0]);
     }
     else if (IsUFix(from) && IsSFix(to))
     {
         var fromFmt = UFix.GetFormat(from);
         var toFmt   = SFix.GetFormat(to);
         int interIW = toFmt.IntWidth - 1;
         int interFW = toFmt.FracWidth;
         if (interIW != fromFmt.IntWidth ||
             interFW != fromFmt.FracWidth)
         {
             var interType = UFix.MakeType(interIW, interFW);
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType));
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to));
         }
         else
         {
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to));
         }
         return(new InstructionDependency[0]);
     }
     else if (IsSLV(from))
     {
         int wfrom = TypeLowering.Instance.GetWireWidth(from);
         int wto   = TypeLowering.Instance.GetWireWidth(to);
         if (wfrom == wto)
         {
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to));
         }
         else
         {
             var interType = StdLogicVector.MakeType(wto);
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType));
             Convert(interType, to);
         }
         return(new InstructionDependency[0]);
     }
     else if (IsSLV(to))
     {
         int wfrom = TypeLowering.Instance.GetWireWidth(from);
         int wto   = TypeLowering.Instance.GetWireWidth(to);
         if (wfrom == wto)
         {
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to));
         }
         else
         {
             var interType = StdLogicVector.MakeType(wfrom);
             Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType));
             Convert(interType, to);
         }
         return(new InstructionDependency[0]);
     }
     else
     {
         Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to));
         return(new InstructionDependency[0]);
     }
 }