public void CreateControlpath(FlowMatrix flowSpec, string procName) { int ncsteps = flowSpec.NumCSteps; string report = _mcd.ComputeEncoding(flowSpec, _maxSelWidth); _curCW = (SLVSignal)_binder.GetSignal <StdLogicVector>(EPortUsage.Default, "CurCW", null, StdLogicVector._0s(_mcd.CWWidth)); var clkInst = _binder.GetSignal <StdLogic>(EPortUsage.Clock, "Clk", null, '0'); if (_staged) { _mcd.CreateStagedDecoder(_binder, _curCW, (SLSignal)clkInst, _registered); } else { _mcd.CreateDecoder(_binder, _curCW); } CreateROM(ncsteps); for (int cstep = 0; cstep < ncsteps; cstep++) { var cw = _mcd.Encode(cstep, flowSpec.GetFlow(cstep)); _romIf.PreWrite(StdLogicVector.FromUInt((uint)cstep, _pc.Size), cw); } var syncTempl = new SyncTemplate(this); var syncFunc = syncTempl.GetAlgorithm(); _binder.CreateProcess(SystemSharp.Components.Process.EProcessKind.Triggered, syncFunc, clkInst.Descriptor); _host.Descriptor.GetDocumentation().Documents.Add(new Document(procName + "_HMA_report.txt", report)); }
public void Encode(int cstep, ParFlow pflow, ref StdLogicVector cw) { foreach (var flow in pflow.Flows) { if (FlowMatrix.IsDontCareFlow(flow)) { continue; } var vflow = flow as ValueFlow; if (vflow != null) { int offs = _vfc.GetValueWordOffset(flow.Target); var ser = Marshal.SerializeForHW(vflow.Value); cw[offs + ser.Size - 1, offs] = ser; } } if (SelWidth <= 0) { return; } int symbol = _encFlow.EncodedSymbols[cstep]; if (symbol == 0) { symbol = 1; } uint index = (uint)(symbol - 1); cw[SelOffset + SelWidth - 1, SelOffset] = StdLogicVector.FromUInt(index, SelWidth); }
public IEnumerable <TAVerb> BranchIfNot(ISignalSource <StdLogicVector> cond, BranchLabel target) { yield return(Verb(ETVMode.Locked, _host.BrP.Dual.Drive(SignalSource.Create <StdLogicVector>("0")), _host.BrN.Dual.Drive(cond), _host.AltAddr.Dual.Drive( SignalSource.Create( StdLogicVector.FromUInt( (uint)target.CStep, _host.AddrWidth))))); for (int i = 1; i < _host.Latency; i++) { yield return(NopVerb()); } }
internal void AssembleDecoder(IAlgorithmBuilder pbuilder, SLVSignal cwSignal, HashSet <ISignalOrPortDescriptor> sensitivity) { if (_encFlow.NumSymbols == 0) { foreach (var target in _targets) { pbuilder.Store(target, LiteralReference.CreateConstant(target.Desc.InitialValue)); } } else if (_encFlow.NumSymbols == 1) { var pflow = _encFlow.BwdEnc[0]; foreach (var flow in pflow.Flows) { ImplementFlow(flow, pbuilder, cwSignal, sensitivity); } } else { var lrCWSelSlice = new LiteralReference( ((ISignal)cwSignal[SelOffset + SelWidth - 1, SelOffset]) .ToSignalRef(SignalRef.EReferencedProperty.Cur)); pbuilder.Switch(lrCWSelSlice); for (int i = 0; i < _encFlow.NumSymbols; i++) { var selValue = StdLogicVector.FromUInt((uint)i, SelWidth); var pflow = _encFlow.BwdEnc[i]; if (i + 1 == _encFlow.NumSymbols) { pbuilder.DefaultCase(); } else { pbuilder.Case(LiteralReference.CreateConstant(selValue)); } foreach (var flow in pflow.Flows) { ImplementFlow(flow, pbuilder, cwSignal, sensitivity); } pbuilder.EndCase(); } pbuilder.EndSwitch(); } }
public virtual void AssembleStagedDecoderSync(int[] syms, int selWidth, LiteralReference lrCWSelSlice, IAutoBinder binder, IAlgorithmBuilder pbuilder, bool registered) { if (NumSymbols < 2) { return; } CreateSelSymbol(binder, registered); pbuilder.Switch(lrCWSelSlice); for (int i = 0; i < syms.Length; i++) { var selValue = StdLogicVector.FromUInt((uint)i, selWidth); pbuilder.Case(LiteralReference.CreateConstant(selValue)); int sym = syms[i]; var symbol = _selSymbols.GetValue(sym - 1); pbuilder.Store( _symbol.SignalInstance.ToSignalRef(SignalRef.EReferencedProperty.Next), LiteralReference.CreateConstant(symbol)); pbuilder.EndCase(); } pbuilder.DefaultCase(); { pbuilder.Store( _symbol.SignalInstance.ToSignalRef(SignalRef.EReferencedProperty.Next), LiteralReference.CreateConstant(StdLogicVector.Xs(NumSymbols))); } pbuilder.EndCase(); if (registered) { pbuilder.Store( _symbold.SignalInstance.ToSignalRef(SignalRef.EReferencedProperty.Next), _symbol.SignalInstance.ToSignalRef(SignalRef.EReferencedProperty.Cur)); } pbuilder.EndSwitch(); }
private void DoMemoryClustering() { var lookup = _eqRegs.ToLookup(); int[] indices = lookup.Select(grp => grp.Key).Where(i => !IsUnused(i)).ToArray(); if (indices.Length == 0) { return; } _eqMems = new UnionFind <int>(new IndexedIntSetAdapter(indices), indices); _writeTimes = new SortedSet <int> [_tempRegTypes.Length]; _readTimes = new SortedSet <int> [_tempRegTypes.Length]; for (int i = 0; i < indices.Length; i++) { int j = indices[i]; _writeTimes[j] = new SortedSet <int>(); _readTimes[j] = new SortedSet <int>(); _writeTimes[j].AddRange(_lifeTimes[j].LeftPoints); _readTimes[j].AddRange(_lifeTimes[j].RightPoints); } bool found; do { found = false; for (int i = 0; i < indices.Length; i++) { int slot1 = indices[i]; for (int j = i + 1; j < indices.Length; j++) { int slot2 = indices[j]; if (AreSharableInMemory(slot1, slot2)) { int rep1 = _eqMems.Find(slot1); int rep2 = _eqMems.Find(slot2); if (rep1 == rep2) { continue; } var mergedInputs = _regIn[slot1].Union(_regIn[slot2]); int newRegMuxCost = mergedInputs.Count(); var commonTargets = _regOut[slot1].Intersect(_regOut[slot2]); if (!commonTargets.Any()) { continue; } int newFuMuxCost = commonTargets.Select(t => ComputeFuMuxCost(t) - 1).Max(); if (newFuMuxCost - newRegMuxCost >= -1) { _eqMems.Union(slot1, slot2); _regIn[slot1].UnionWith(_regIn[slot2]); _regIn[slot2] = _regIn[slot1]; int rep = _eqMems.Find(slot1); if (rep != rep1) { _writeTimes[rep].AddRange(_writeTimes[rep1]); _readTimes[rep].AddRange(_readTimes[rep1]); } if (rep != rep2) { _writeTimes[rep].AddRange(_writeTimes[rep2]); _readTimes[rep].AddRange(_readTimes[rep2]); } found = true; } } } } } while (found); _memLookup = _eqMems.ToLookup(); _memAddrs = new StdLogicVector[_tempRegTypes.Length]; foreach (var grp in _memLookup) { var active = grp.Where(i => !IsUnused(i)); if (active.Count() <= 1) { continue; } int addrWidth = MathExt.CeilLog2(active.Count()); uint addr = 0; foreach (var stgSlot in active) { if (IsUnused(stgSlot)) { continue; } _memAddrs[stgSlot] = StdLogicVector.FromUInt(addr, addrWidth); addr++; } } }