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; }