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