public FPUWrapper(EISEVersion iseVer)
 {
     var a = new SLVSignal(32);
     var b = new SLVSignal(32);
     var r = new SLVSignal(32);
     var clk = new SLSignal();
     _fpu = new FloatingPointCore()
     {
         A = a,
         B = b,
         Clk = clk,
         Result = r,
         DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage,
         Function = FloatingPointCore.EFunction.AddSubtract,
         TargetDeviceFamily = SystemSharp.Interop.Xilinx.EDeviceFamily.Virtex6,
         UseMaximumLatency = true,
         Precision = FloatingPointCore.EPrecision.Single,
         ResultPrecision = FloatingPointCore.EPrecision.Single,
         AddSubSel = FloatingPointCore.EAddSub.Add,
         TargetISEVersion = iseVer
     };
     Clk = clk;
     A = a;
     B = b;
     R = r;
 }
 public TransactionSite(FloatingPointCore host):
     base(host)
 {
     _host = host;
 }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            XilinxProject xproj = proj as XilinxProject;
            if (xproj == null)
                return null;

            Type otype = operandTypes[0].CILType;
            if (!operandTypes.All(t => t.CILType.Equals(otype)))
                return null;
            Type rtype = resultTypes[0].CILType;
            FloatingPointCore fpu = null;
            CoreConfiguration cfg = null;

            switch (instr.Name)
            {
                case InstructionCodes.Add:
                case InstructionCodes.Sub:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.AddSubtract,
                            Precision = prec,
                            ResultPrecision = prec,
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.AddSubtract];
                        if (cfg.UseDedicatedAddSub)
                        {
                            if (instr.Name.Equals(InstructionCodes.Add))
                                fpu.AddSubSel = FloatingPointCore.EAddSub.Add;
                            else
                                fpu.AddSubSel = FloatingPointCore.EAddSub.Subtract;
                        }
                        else
                        {
                            fpu.AddSubSel = FloatingPointCore.EAddSub.Both;
                        }
                    }
                    break;

                case InstructionCodes.IsEq:
                case InstructionCodes.IsGt:
                case InstructionCodes.IsGte:
                case InstructionCodes.IsLt:
                case InstructionCodes.IsLte:
                case InstructionCodes.IsNEq:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Compare,
                            Precision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Compare];
                        if (cfg.UseDedicatedCmp)
                        {
                            switch (instr.Name)
                            {
                                case InstructionCodes.IsEq:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.Equal;
                                    break;
                                case InstructionCodes.IsGt:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThan;
                                    break;
                                case InstructionCodes.IsGte:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThanOrEqual;
                                    break;
                                case InstructionCodes.IsLt:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.LessThan;
                                    break;
                                case InstructionCodes.IsLte:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.LessThanOrEqual;
                                    break;
                                case InstructionCodes.IsNEq:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.NotEqual;
                                    break;
                                default:
                                    throw new NotImplementedException();
                            }
                        }
                        else
                        {
                            fpu.CompareSel = FloatingPointCore.ECompareOp.Programmable;
                        }

                        fpu.ResultPrecision = FloatingPointCore.EPrecision.Custom;
                        fpu.ResultExponentWidth = 1;
                        fpu.ResultFractionWidth = 0;
                    }
                    break;

                case InstructionCodes.Mul:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Multiply,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Multiply];
                    }
                    break;

                case InstructionCodes.Div:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Divide,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Divide];
                    }
                    break;

                case InstructionCodes.Sqrt:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.SquareRoot,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.SquareRoot];
                    }
                    break;

                case InstructionCodes.Convert:
                    {
                        FloatingPointCore.EPrecision inprec = FloatingPointCore.EPrecision.Single;
                        bool infloat = false;
                        FixFormat infmt = null;
                        if (otype.Equals(typeof(float)))
                        {
                            inprec = FloatingPointCore.EPrecision.Single;
                            infloat = true;
                        }
                        else if (otype.Equals(typeof(double)))
                        {
                            inprec = FloatingPointCore.EPrecision.Double;
                            infloat = true;
                        }
                        else if (otype.Equals(typeof(SFix)) ||
                            otype.Equals(typeof(Signed)))
                        {
                            inprec = FloatingPointCore.EPrecision.Custom;
                            infloat = false;
                            infmt = SFix.GetFormat(operandTypes[0]);
                        }
                        else
                        {
                            return null;
                        }

                        FloatingPointCore.EPrecision outprec = FloatingPointCore.EPrecision.Single;
                        bool outfloat = false;
                        FixFormat outfmt = null;
                        if (rtype.Equals(typeof(float)))
                        {
                            outprec = FloatingPointCore.EPrecision.Single;
                            outfloat = true;
                        }
                        else if (rtype.Equals(typeof(double)))
                        {
                            outprec = FloatingPointCore.EPrecision.Double;
                            outfloat = true;
                        }
                        else if (rtype.Equals(typeof(SFix)) ||
                            rtype.Equals(typeof(Signed)))
                        {
                            outprec = FloatingPointCore.EPrecision.Custom;
                            outfloat = false;
                            outfmt = SFix.GetFormat(resultTypes[0]);
                        }
                        else
                        {
                            return null;
                        }

                        FloatingPointCore.EFunction func;
                        if (!infloat && !outfloat)
                            return null;
                        else if (infloat && outfloat)
                            func = FloatingPointCore.EFunction.FloatToFloat;
                        else if (infloat)
                            func = FloatingPointCore.EFunction.FloatToFixed;
                        else
                            func = FloatingPointCore.EFunction.FixedToFloat;

                        fpu = new FloatingPointCore()
                        {
                            Function = func,
                            Precision = inprec,
                            ResultPrecision = outprec
                        };
                        if (infmt != null)
                        {
                            fpu.ExponentWidth = infmt.IntWidth;
                            fpu.FractionWidth = infmt.FracWidth;
                        }
                        if (outfmt != null)
                        {
                            fpu.ResultExponentWidth = outfmt.IntWidth;
                            fpu.ResultFractionWidth = outfmt.FracWidth;
                        }
                        FloatingPointCore.EPrecision prec = infloat ? inprec : outprec;
                        cfg = Config[prec, FloatingPointCore.EFunction.Multiply];
                    }
                    break;

                default:
                    return null;
            }
            fpu.TargetDeviceFamily = xproj.DeviceFamily;
            fpu.TargetISEVersion = xproj.ISEVersion;
            if (cfg.EnableDeviceCapabilityDependentDSPUsage)
            {
                switch (fpu.Function)
                {
                    case FloatingPointCore.EFunction.Multiply:
                        switch (xproj.DeviceFamily)
                        {
                            case EDeviceFamily.Spartan3:
                            case EDeviceFamily.Spartan3A_3AN:
                            case EDeviceFamily.Spartan3E:
                            case EDeviceFamily.Automotive_Spartan3:
                            case EDeviceFamily.Automotive_Spartan3A:
                            case EDeviceFamily.Automotive_Spartan3E:
                                if (cfg.DSPUsageRatio < 0.5f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                else
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                break;

                            default:
                                if (cfg.DSPUsageRatio < 0.25f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                else if (cfg.DSPUsageRatio < 0.50f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MediumUsage;
                                else if (cfg.DSPUsageRatio < 0.75f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MaxUsage;
                                else
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                break;
                        }
                        break;

                    case FloatingPointCore.EFunction.AddSubtract:
                        if (fpu.Precision == FloatingPointCore.EPrecision.Custom)
                        {
                            fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                        }
                        else
                        {
                            switch (xproj.DeviceFamily)
                            {
                                case EDeviceFamily.Virtex4:
                                case EDeviceFamily.Virtex5:
                                case EDeviceFamily.Virtex6:
                                case EDeviceFamily.Virtex6_LowPower:
                                    if (cfg.DSPUsageRatio < 0.5f)
                                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                    else
                                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                    break;

                                default:
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                    break;
                            }
                        }
                        break;

                    default:
                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                        break;
                }
            }
            else
            {
                fpu.DSP48EUsage = cfg.DSP48EUsage;
            }
            fpu.HasCE = cfg.HasCE;
            fpu.HasDivideByZero = cfg.HasDivideByZero;
            fpu.HasInvalidOp = cfg.HasInvalidOp;
            fpu.HasOperationND = cfg.HasOperationND;
            fpu.HasOperationRFD = cfg.HasOperationRFD;
            fpu.HasOverflow = cfg.HasOverflow;
            fpu.HasRdy = cfg.HasRdy;
            fpu.HasSCLR = cfg.HasSCLR;
            if (cfg.UseMaximumLatency)
            {
                fpu.UseMaximumLatency = true;
            }
            else if (cfg.SpecifyLatencyRatio)
            {
                fpu.UseMaximumLatency = false;
                fpu.Latency = (int)(cfg.LatencyRatio * fpu.MaximumLatency);
            }
            else
            {
                fpu.Latency = cfg.Latency;
            }
            IXILMapping result = TryMapOne(fpu.TASite, instr, operandTypes, resultTypes, false);
            Debug.Assert(result != null);
            return result;
        }
 /// <summary>
 /// Retrieves the configuration options for a given precision and functional selection.
 /// </summary>
 public CoreConfiguration this[FloatingPointCore.EPrecision prec, FloatingPointCore.EFunction func]
 {
     get { return _map[Tuple.Create(prec, func)]; }
 }