public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (instr.Name != InstructionCodes.Mul) { return(null); } FixFormat fmta, fmtb, fmtr; fmta = GetFixFormat(operandTypes[0]); fmtb = GetFixFormat(operandTypes[1]); fmtr = GetFixFormat(resultTypes[0]); if (fmta == null || fmtb == null || fmtr == null) { return(null); } bool expectSigned = fmta.IsSigned || fmtb.IsSigned; if (expectSigned != fmtr.IsSigned) { return(null); } int high = fmtr.IntWidth + fmta.FracWidth + fmtb.FracWidth - 1; int low = fmta.FracWidth + fmtb.FracWidth - fmtr.FracWidth; var xproj = proj as XilinxProject; XilinxMultiplier.EGenerator gen = XilinxMultiplier.EGenerator.Multiplier_11_2; switch (xproj.ISEVersion) { case EISEVersion._11_1: case EISEVersion._11_2: case EISEVersion._11_3: case EISEVersion._11_4: case EISEVersion._11_5: gen = XilinxMultiplier.EGenerator.Multiplier_11_0; break; } XilinxMultiplier mul = new XilinxMultiplier() { Generator = gen, HasCE = false, MultiplierConstruction = XilinxMultiplier.EConstruction.UseMults, MultType = XilinxMultiplier.EMultiplierType.ParallelMultiplier, OptGoal = XilinxMultiplier.EOptimizationGoal.Speed, UseCustomOutputWidth = true, OutputWidthHigh = high, OutputWidthLow = low, PortAType = fmta.IsSigned ? XilinxMultiplier.ESignedness.Signed : XilinxMultiplier.ESignedness.Unsigned, PortAWidth = fmta.TotalWidth, PortBType = fmtb.IsSigned ? XilinxMultiplier.ESignedness.Signed : XilinxMultiplier.ESignedness.Unsigned, PortBWidth = fmtb.TotalWidth, HasSCLR = false, UseRounding = false, ZeroDetect = false }; int optStages = ComputeOptimalPipeStages(mul); { // debug only DesignContext.Push(); var mul2 = new XilinxMultiplier() { Generator = gen, HasCE = false, MultiplierConstruction = XilinxMultiplier.EConstruction.UseMults, MultType = XilinxMultiplier.EMultiplierType.ParallelMultiplier, OptGoal = XilinxMultiplier.EOptimizationGoal.Speed, UseCustomOutputWidth = true, OutputWidthHigh = high, OutputWidthLow = low, PortAType = fmtb.IsSigned ? XilinxMultiplier.ESignedness.Signed : XilinxMultiplier.ESignedness.Unsigned, PortAWidth = fmtb.TotalWidth, PortBType = fmta.IsSigned ? XilinxMultiplier.ESignedness.Signed : XilinxMultiplier.ESignedness.Unsigned, PortBWidth = fmta.TotalWidth, HasSCLR = false, UseRounding = false, ZeroDetect = false }; Debug.Assert(optStages == ComputeOptimalPipeStages(mul2)); DesignContext.Pop(); } int scaledStages = (int)Math.Round(Config.PipeStageScaling * optStages); mul.PipeStages = scaledStages; return(new XILMapping(mul, false)); }
/// <summary> /// Executes the HLS design flow. /// </summary> /// <param name="design">the design</param> /// <param name="host">the hosting component</param> /// <param name="proc">the process being subject to HLS</param> /// <param name="targetProject">the target project</param> /// <remarks>Inside the hosting component, the process will be replaced by the synthesized hardware.</remarks> public void Execute(DesignContext design, Component host, ProcessDescriptor proc, IProject targetProject) { Contract.Requires <ArgumentNullException>(design != null); Contract.Requires <ArgumentNullException>(host != null); Contract.Requires <ArgumentNullException>(proc != null); Contract.Requires <ArgumentNullException>(targetProject != null); design.CurrentProcess = proc.Instance; var clk = proc.Sensitivity[0]; SignalBase clkI; var sdClk = clk as SignalDescriptor; if (sdClk == null) { clkI = ((SignalDescriptor)((PortDescriptor)clk).BoundSignal).Instance; } else { clkI = sdClk.Instance; } var state = new HLSState(this, design, host, proc, targetProject); proc.AddAttribute(state); if (_beginHLS != null) { _beginHLS(state); } var dpb = new DefaultDatapathBuilder(host, clkI, proc.Name); state.InterconnectBuilder = InterconnectBuilder.Create(host, dpb.ICBinder); state.ControlpathBuilder = ControlPathBuilder.Create(host, dpb.FUBinder); state.ControlpathBuilder.PersonalizePlan(this); do { XILSFunction fnasm; if (!proc.HasAttribute <XILSFunction>()) { var func = proc.Implementation; IEnumerable <Function> inlinedFunctions; func = func.InlineCalls(out inlinedFunctions); if (ConvertFieldsToLocals) { Variable[] newLocals; func = func.ConvertFieldsToLocals(out newLocals); } state.PreprocessedFunction = func; fnasm = state.PreprocessedFunction.Compile(DefaultInstructionSet.Instance); } else { fnasm = proc.QueryAttribute <XILSFunction>(); } fnasm.SanityCheck(); state.XILSInput = fnasm; IList <XILSInstr> instrs = state.XILSInput.Instructions.ToList(); foreach (var rw in XILSTransformations) { instrs = rw.Rewrite(instrs); fnasm = new XILSFunction(fnasm.Name, fnasm.Arguments, fnasm.Locals, instrs.ToArray()); fnasm.SanityCheck(); } state.XILSTransformed = fnasm; XIL3Function fnasm3 = fnasm.ToXIL3(); state.XIL3Input = fnasm3; foreach (IXIL3Rewriter rw in XIL3Transformations) { fnasm3 = rw.Rewrite(fnasm3); fnasm3.SanityCheck(); } state.XIL3Transformed = fnasm3; state.NotifyProgress(EHLSProgress.Compiled); } while (state._repeat); if (state._cancel) { return; } SchedulingConstraints constraints; do { var xmm = new XILMapperManager(); foreach (var dpu in Enumerable.Reverse(XILMappers)) { xmm.AddMapper(dpu); } DesignContext.Push(); var xilsa = new XILSchedulingAdapter(state.XIL3Transformed, xmm, host, targetProject); if (AllocationPolicy != null) { xilsa.Allocator.Policy = AllocationPolicy.Create(); } if (_onFUCreated != null) { xilsa.Allocator.OnFUAllocation += _onFUCreated; } state.SchedulingAdapter = xilsa; state.NotifyProgress(EHLSProgress.AboutToSchedule); constraints = SchedulingConstraints; if (constraints == null) { if (proc.Implementation != null) { constraints = proc.Implementation.QueryAttribute <SchedulingConstraints>(); } if (constraints == null) { constraints = new SchedulingConstraints(); } } state.Constraints = constraints; if (constraints.MinimizeNumberOfFUs) { foreach (var instr in state.XIL3Transformed.Instructions) { xilsa.SetMaxFUAllocation(xilsa.IClass[instr], 1); } } Scheduler.Schedule(xilsa.CFG, constraints, xilsa); DesignContext.Pop(); state.NotifyProgress(EHLSProgress.Scheduled); } while (state._repeat); ComputeCStepsForBranchTargets(state.SchedulingAdapter); do { state.ControlpathBuilder.PrepareAllocation(state.SchedulingAdapter.ComputeCStepCount()); var flowSpec = state.SchedulingAdapter.Allocate(dpb); state.RawFlows = flowSpec; var realFlow = new FlowMatrix(); state.InterconnectBuilder.CreateInterconnect(flowSpec, realFlow); state.RealFlows = realFlow; state.NotifyProgress(EHLSProgress.InterconnectCreated); } while (state._repeat); if (state._cancel) { return; } Debug.Assert(state.RealFlows.FlowSources.All(sr => sr.Desc.Owner != null)); Debug.Assert(state.RealFlows.FlowTargets.All(sr => sr.Desc.Owner != null)); do { state.ControlpathBuilder.CreateControlpath(state.RealFlows, proc.Name); foreach (var prof in constraints.Profilers) { prof.ExtractFrom(state.XIL3Transformed, state.SchedulingAdapter); } state.NotifyProgress(EHLSProgress.ControlpathCreated); } while (state._repeat); if (state._cancel) { return; } }