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));
        }
Exemple #2
0
        /// <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;
            }
        }