/// <summary>
        /// Performs resource allocation and binding.
        /// </summary>
        /// <param name="dpb">datapath builder to use</param>
        /// <returns>resulting flow matrix</returns>
        public FlowMatrix Allocate(IDatapathBuilder dpb)
        {
            // Step 1: create intermediate storage for each instruction output slot
            var tempSignals = new SLVSignal[_func.SlotTypes.Length];

            for (int i = 0; i < _func.SlotTypes.Length; i++)
            {
                int width   = TypeLowering.Instance.GetWireWidth(_func.SlotTypes[i]);
                var initial = StdLogicVector.Us(width);
                tempSignals[i] = (SLVSignal)Signals.CreateInstance(initial);
                tempSignals[i].Descriptor.TagTemporary(i);
            }

            // Step 2: Allocate and establish unit bindings
            Action <IXILMapping> onAlloc = map => dpb.AddFU(map.TASite.Host);

            _alloc.OnFUAllocation += onAlloc;
            var mappings = new Dictionary <int, IXILMapping>();

            foreach (var xil3i in _func.Instructions)
            {
                TypeDescriptor[] otypes = xil3i.OperandSlots.Select(i => _func.SlotTypes[i]).ToArray();
                TypeDescriptor[] rtypes = xil3i.ResultSlots.Select(i => _func.SlotTypes[i]).ToArray();
                long             cstep  = CStep[xil3i];
                var mapping             = _alloc.TryBind(xil3i, cstep, otypes, rtypes);
                if (mapping == null)
                {
                    throw new XILSchedulingFailedException("Realization failed: " + xil3i.Command);
                }
                mappings[xil3i.Index] = mapping;
                mapping.TASite.Establish(dpb.FUBinder);
                Allocator.Policy.TellMapping(xil3i, cstep, mapping);
            }
            _alloc.OnFUAllocation -= onAlloc;

            // Step 3: Assemble flow matrix
            var result = new FlowMatrix();

            foreach (var xil3i in _func.Instructions)
            {
                long cstep   = CStep[xil3i];
                var  mapping = mappings[xil3i.Index];
                result.AddNeutral(mapping.TASite.DoNothing());
                var impl = mapping.Realize(
                    xil3i.OperandSlots.Select(s => tempSignals[s].AsSignalSource <StdLogicVector>()).ToArray(),
                    xil3i.ResultSlots.Select(s => tempSignals[s].AsCombSink()).ToArray());
                if (impl.Count() - Latency[xil3i] > 1)
                {
                    throw new XILSchedulingFailedException("Mapping length exceeds scheduled latency");
                }
                result.Add((int)cstep, impl);
                result.AppendComment((int)cstep, ToComment(xil3i));
                _mappingCache[xil3i.Index] = mapping;
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Creates and adds a new signal, including its implementation-level instance.
        /// </summary>
        /// <param name="me">component descriptor to host the new signal</param>
        /// <param name="name">name of new signal</param>
        /// <param name="initialValue">initial value of new signal</param>
        /// <returns>the descriptor for the newly created signal</returns>
        public static SignalDescriptor CreateSignalInstance(this IComponentDescriptor me, string name, object initialValue)
        {
            Contract.Requires <ArgumentNullException>(me != null);
            Contract.Requires <ArgumentNullException>(initialValue != null);
            Contract.Requires <ArgumentNullException>(name != null);

            SignalBase       sinst  = Signals.CreateInstance(initialValue);
            SignalDescriptor result = sinst.Descriptor;

            me.AddChild(result, name);
            return(result);
        }
 public SignalBase GetSignal(EPortUsage portUsage, string portName, string domainID, object initialValue)
 {
     return(Signals.CreateInstance(initialValue));
 }
示例#4
0
        private IEnumerable <ITimedFlow> ConstructNetwork(SignalRef target, IEnumerable <ITimedFlow> flows)
        {
            var groupedByDelay = flows
                                 .GroupBy(tf => tf is TimedSignalFlow ? ((TimedSignalFlow)tf).Delay : 0)
                                 .OrderBy(grp => grp.Key);
            var  curTarget      = target;
            int  remainingFanIn = flows.Count();
            long generation     = 0;
            var  pumpOut        = new List <SignalFlow>();

            foreach (var delayGroup in groupedByDelay)
            {
                foreach (var tflow in delayGroup)
                {
                    var tsf = tflow as TimedSignalFlow;
                    var tvf = tflow as TimedValueFlow;
                    if (tsf != null)
                    {
                        long flowDelay = tsf.Delay - generation;
                        if (flowDelay == 0)
                        {
                            yield return(new TimedSignalFlow(tsf.Source, curTarget, tsf.Time, 0));
                        }
                        else
                        {
                            SignalBase tmpSig = Signals.CreateInstance(tsf.Source.Desc.InitialValue);
                            tmpSig.Descriptor.TagTemporary(_tmpIdx++);
                            yield return(new TimedSignalFlow(
                                             tsf.Source,
                                             tmpSig.ToSignalRef(SignalRef.EReferencedProperty.Next),
                                             tsf.Time, 0));

                            yield return(new TimedSignalFlow(
                                             tmpSig.ToSignalRef(SignalRef.EReferencedProperty.Cur),
                                             curTarget,
                                             tsf.Time + flowDelay, 0));
                        }
                        long start = tsf.Time + tsf.Delay;
                        foreach (var pump in pumpOut)
                        {
                            yield return(new TimedSignalFlow(pump.Source, pump.Target, start, 0));

                            start--;
                        }
                    }
                    else
                    {
                        // remark: as of now, delay is always 0
                        yield return(new TimedValueFlow(tvf.Value, curTarget, tvf.Time));
                    }
                }
                long delay = delayGroup.Key;
                remainingFanIn -= delayGroup.Count();
#if false
                if (remainingFanIn > 1)
                {
                    var stageInSignal = _binder.GetSignal(EPortUsage.Default,
                                                          "icn_" + target.Desc.Name + "_" + generation + "_in",
                                                          null,
                                                          target.Desc.InitialValue);
                    var stageOutSignal = _binder.GetSignal(EPortUsage.Default,
                                                           "icn_" + target.Desc.Name + "_" + generation + "_out",
                                                           null,
                                                           target.Desc.InitialValue);
                    _stageInSignals.Add(stageInSignal);
                    _stageOutSignals.Add(stageOutSignal);
                    var pumpSource = new SignalRef(stageOutSignal.ToSignalRef(SignalRef.EReferencedProperty.Cur));
                    pumpOut.Add(new SignalFlow(pumpSource, curTarget));
                    curTarget = new SignalRef(stageInSignal.ToSignalRef(SignalRef.EReferencedProperty.Next));
                    ++generation;
                }
#endif
            }
        }