コード例 #1
0
        private void HandleSqrt(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, i.OperandTypes, i.ResultTypes));
            }
            else
            {
                var nrtype = UFix.MakeType((oformat.IntWidth + 2) / 2, rformat.FracWidth);
                if (oformat.IntWidth % 2 == 0)
                {
                    var itype = UFix.MakeType(oformat.IntWidth + 1, oformat.FracWidth);
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, i.OperandTypes[0], itype));
                    Emit(i.Command.CreateStk(1, itype, nrtype));
                }
                else
                {
                    Emit(i.Command.CreateStk(1, i.OperandTypes[0], nrtype));
                }
                if (!nrtype.Equals(i.ResultTypes[0]))
                {
                    Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, nrtype, i.ResultTypes[0]));
                }
            }
        }
コード例 #2
0
ファイル: XILResultTypes.cs プロジェクト: cephdon/systemsharp
        /// <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();
            }
        }
コード例 #3
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());
            }
        }
コード例 #4
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]);
     }
 }