private void ComputeLifetimes() { for (int i = 0; i < _flowSpec.NumCSteps; i++) { var pflow = _flowSpec.GetFlow(i); foreach (var flow in pflow.Flows) { int tindex = flow.Target.GetTemporaryIndex(); if (tindex >= 0) { _lifeStart[tindex] = Math.Min(_lifeStart[tindex], i); } var sflow = flow as SignalFlow; if (sflow != null) { int sindex = sflow.Source.GetTemporaryIndex(); if (sindex >= 0) { _lifeEnd[sindex] = Math.Max(_lifeEnd[sindex], i + 1); } } } } for (int i = 0; i < _lifeStart.Length; i++) { Debug.Assert(!IsMayfly(i)); } }
private void Init() { var tempTargets = _flowSpec.FlowTargets.Select(t => t.GetTemporaryIndex()); int maxRegs = tempTargets.Max() + 1; int scount = maxRegs; _tempRegTypes = new TypeDescriptor[scount]; //_regMuxCost = Enumerable.Repeat(1, scount).ToArray(); _fuMuxIn = new Dictionary <SignalRef, HashSet <int> >(); _regOut = new HashSet <SignalRef> [scount]; _regIn = new HashSet <SignalRef> [scount]; for (int i = 0; i < scount; i++) { _regIn[i] = new HashSet <SignalRef>(); _regOut[i] = new HashSet <SignalRef>(); } foreach (var target in _flowSpec.FlowTargets) { if (target.IsTemporary()) { int index = target.GetTemporaryIndex(); _tempRegTypes[index] = target.Desc.ElementType; } } for (int cstep = 0; cstep < _flowSpec.NumCSteps; cstep++) { var pflow = _flowSpec.GetFlow(cstep); foreach (var flow in pflow.Flows) { var sflow = flow as SignalFlow; if (sflow != null && sflow.Source.IsTemporary()) { int sindex = sflow.Source.GetTemporaryIndex(); _fuMuxIn.Add(sflow.Target, sindex); _regOut[sindex].Add(sflow.Target); } if (sflow != null && flow.Target.IsTemporary()) { int tindex = flow.Target.GetTemporaryIndex(); _regIn[tindex].Add(sflow.Source); } } } _lifeStart = new int[scount]; _lifeEnd = new int[scount]; for (int i = 0; i < scount; i++) { _lifeStart[i] = int.MaxValue; _lifeEnd[i] = int.MinValue; } _eqRegs = new UnionFind <int>(new IntSetAdapter(), Enumerable.Range(0, scount).ToList()); _lifeTimes = new IntervalSet[scount]; }
private void BuildFlowMap() { _elseFlows = new Dictionary <SignalRef, Flow>(); _enablingStatesMap = new Dictionary <Flow, List <object> >(); foreach (Flow flow in _flowSpec.NeutralFlow.Flows) { if (FlowMatrix.IsDontCareFlow(flow)) { var zflow = FlowMatrix.AsDontCareFlow((ValueFlow)flow, StdLogic.Z); _elseFlows[flow.Target] = zflow; } else { NonTristateTargets.Add(flow.Target); } } Array stateValues = _cpb._stateSignal.Descriptor.ElementType.CILType.GetEnumValues(); for (int cstep = 0; cstep < stateValues.Length; cstep++) { var state = stateValues.GetValue(cstep); var pflow = _flowSpec.GetFlow(cstep); foreach (var flow in pflow.Flows) { if (!_enablingStatesMap.ContainsKey(flow)) { _enablingStatesMap[flow] = new List <object>(); } _enablingStatesMap[flow].Add(state); } } }
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)); }
protected override void DeclareAlgorithm() { SignalRef curStateRef = SignalRef.Create(_cpb._stateSignal, SignalRef.EReferencedProperty.Cur); LiteralReference lrCurState = new LiteralReference(curStateRef); Array stateValues = _cpb._stateSignal.Descriptor.ElementType.CILType.GetEnumValues(); // Insert neutral pre-sets _flowSpec.NeutralFlow.ToProcess().Implement(this); // State-dependent MUX Switch(lrCurState); { for (int cstep = 0; cstep < stateValues.Length; cstep++) { Case(LiteralReference.CreateConstant(stateValues.GetValue(cstep))); { Comment(_flowSpec.GetComment(cstep)); _flowSpec.GetFlow(cstep).ToProcess().Implement(this); } EndCase(); } DefaultCase(); { _flowSpec.NeutralFlow.ToProcess().Implement(this); } EndCase(); } EndSwitch(); }
protected override void DeclareAlgorithm() { SignalRef curStateRef = SignalRef.Create(_cpb._stateSignal, SignalRef.EReferencedProperty.Cur); LiteralReference lrCurState = new LiteralReference(curStateRef); Array stateValues = _cpb._stateSignal.Descriptor.ElementType.CILType.GetEnumValues(); // Insert neutral pre-sets var npflow = new ParFlow(); foreach (var flow in _flowSpec.NeutralFlow.Flows) { if (_nonTristateTargets.Contains(flow.Target)) { npflow.Add(flow); } } npflow.ToProcess().Implement(this); // State-dependent MUX Switch(lrCurState); { for (int cstep = 0; cstep < stateValues.Length; cstep++) { Case(LiteralReference.CreateConstant(stateValues.GetValue(cstep))); { Comment(_flowSpec.GetComment(cstep)); var pflow = new ParFlow(); foreach (var flow in _flowSpec.GetFlow(cstep).Flows) { if (_nonTristateTargets.Contains(flow.Target)) { pflow.Add(flow); } } pflow.ToProcess().Implement(this); } EndCase(); } DefaultCase(); { npflow.ToProcess().Implement(this); } EndCase(); } EndSwitch(); }
private void InstantiateControlLogic() { int scount = _flowSpec.FlowTargets.Select(t => t.GetTemporaryIndex()).Max() + 1; _regIndices = new int[scount]; for (int i = 0; i < scount; i++) { _regIndices[i] = -1; } int curReg = 0; for (int i = 0; i < _flowSpec.NumCSteps; i++) { var pflow = _flowSpec.GetFlow(i); foreach (var flow in pflow.Flows) { var sflow = flow as SignalFlow; var target = flow.Target; int tindex = flow.Target.GetTemporaryIndex(); if (sflow != null) { var source = sflow.Source; int sindex = sflow.Source.GetTemporaryIndex(); if (sindex >= 0 && _regIndices[sindex] < 0) { _regIndices[sindex] = curReg++; } } } } int numRegs = curReg; _regsCur = new SignalBase[numRegs]; _regsNext = new SignalBase[numRegs]; foreach (var target in _flowSpec.FlowTargets) { if (!target.IsTemporary()) { continue; } int index = target.GetTemporaryIndex(); int rindex = _regIndices[index]; if (rindex < 0) { continue; } if (_regsCur[rindex] != null) { continue; } string name = "R" + rindex + "_cur"; _regsCur[rindex] = _binder.GetSignal(EPortUsage.Default, name, null, target.Desc.InitialValue); name = "R" + rindex + "_next"; _regsNext[rindex] = _binder.GetSignal(EPortUsage.Default, name, null, target.Desc.InitialValue); } var syncTempl = new SyncTemplate(this); var syncFunc = syncTempl.GetAlgorithm(); Signal <StdLogic> clkInst = _binder.GetSignal <StdLogic>(EPortUsage.Clock, "Clk", null, '0'); _host.Descriptor.CreateProcess(SystemSharp.Components.Process.EProcessKind.Triggered, syncFunc, clkInst.Descriptor); }
public string ComputeEncoding(FlowMatrix flowSpec, int maxSelWidth = 6) { var sb = new StringBuilder(); sb.AppendLine("Control word encoding report"); sb.AppendFormat(" Number of c-steps: {0}", flowSpec.NumCSteps); sb.AppendLine(); sb.AppendFormat(" Maximum LUT inputs: {0}", maxSelWidth); sb.AppendLine(); FlowSpec = flowSpec; var flowMap = new Dictionary<SignalRef, List<Flow>>(); var neutralFlow = flowSpec.NeutralFlow; _vcf.AddFlow(neutralFlow); for (int i = 0; i < flowSpec.NumCSteps; i++) { var pflow = flowSpec.GetFlow(i); var nflow = new ParFlow(neutralFlow); nflow.Integrate(pflow); _vcf.AddFlow(nflow); foreach (var flow in nflow.Flows) { List<Flow> flows; if (!flowMap.TryGetValue(flow.Target, out flows)) { flows = new List<Flow>(); flowMap[flow.Target] = flows; } flows.Add(flow); } } _vcf.Encode(); var startTime = DateTime.Now; var encFlows = flowMap.Values .Select((l, i) => new EncodedFlow(l, i)).ToArray(); var uncompressedMuxBits = encFlows.Sum(ef => MathExt.CeilLog2(ef.NumSymbols)); sb.AppendFormat(" Uncompressed CW: {0} MUX bits + {1} value bits", uncompressedMuxBits, _vcf.GetUncompressedValueWordWidth()); sb.AppendLine(); int numTargets = encFlows.Length; var mergeCandidates = new List<Tuple<int, int, MergedFlow>>(); var indices = new SortedSet<int>(Enumerable.Range(0, numTargets)); var curGen = (EncodedFlow[])encFlows.Clone(); bool mergedAny; var nextCandidates = new List<Tuple<int, int, MergedFlow>>(); do { foreach (int i in indices) { if (curGen[i].NumSymbols <= 1) continue; var upview = indices.GetViewBetween(i + 1, numTargets); foreach (int j in upview) { if (curGen[j].NumSymbols <= 1) continue; var mergedFlow = new MergedFlow(curGen[i], curGen[j]); mergeCandidates.Add(Tuple.Create(i, j, mergedFlow)); } } var orderedMergeCandidates = mergeCandidates.OrderByDescending(t => t.Item3.Score); var nextGen = (EncodedFlow[])curGen.Clone(); var mergedIndices = new HashSet<int>(); var mergedLowIndices = new SortedSet<int>(); var mergedHiIndices = new HashSet<int>(); mergedAny = false; foreach (var tup in orderedMergeCandidates) { Debug.Assert(tup.Item2 > tup.Item1); var mergedFlow = tup.Item3; if (mergedFlow.Score == 0.0) break; int selWidth = MathExt.CeilLog2(mergedFlow.NumSymbols); if (selWidth > maxSelWidth) continue; if (mergedIndices.Contains(tup.Item1) || mergedIndices.Contains(tup.Item2)) continue; mergedIndices.Add(tup.Item1); mergedIndices.Add(tup.Item2); mergedLowIndices.Add(tup.Item1); mergedHiIndices.Add(tup.Item2); indices.Remove(tup.Item2); mergedFlow.Realize(); Debug.Assert(nextGen[tup.Item1].Targets.All(t => mergedFlow.Targets.Contains(t))); Debug.Assert(nextGen[tup.Item2].Targets.All(t => mergedFlow.Targets.Contains(t))); nextGen[tup.Item1] = mergedFlow; mergedAny = true; } nextCandidates.Clear(); curGen = nextGen; mergeCandidates.Clear(); mergeCandidates.AddRange(nextCandidates); } while (mergedAny); _strings = indices.Select(i => new MicroString(curGen[i], _vcf)).ToArray(); // Verification var coveredTargets = _strings.SelectMany(s => s.Targets); var allTargets = encFlows.SelectMany(f => f.Targets); var isect0 = coveredTargets.Except(allTargets); var isect1 = allTargets.Except(coveredTargets); Debug.Assert(!isect0.Any()); Debug.Assert(!isect1.Any()); // int offset = _vcf.ValueWordWidth; int order = 0; foreach (var ms in _strings) { ms.SelOffset = offset; ms.Order = order; offset += ms.SelWidth; order++; } CWWidth = offset; var stopTime = DateTime.Now; var runTime = stopTime - startTime; sb.AppendFormat(" Compressed CW: {0} MUX bits + {1} value bits", offset - _vcf.ValueWordWidth, _vcf.ValueWordWidth); sb.AppendLine(); sb.AppendFormat(" Maximum LUT inputs: {0}", _strings.Max(s => s.SelWidth)); sb.AppendFormat(" Running time: {0} ms", runTime.TotalMilliseconds); sb.AppendLine(); sb.AppendLine(); sb.AppendLine("Number of MUX inputs; Number of occurences"); var histo = _strings.GroupBy(s => s.SelWidth) .OrderByDescending(grp => grp.Key); foreach (var grp in histo) { sb.AppendFormat("{0}; {1}", grp.Key, grp.Count()); sb.AppendLine(); } return sb.ToString(); }
public string ComputeEncoding(FlowMatrix flowSpec, int maxSelWidth = 6) { var sb = new StringBuilder(); sb.AppendLine("Control word encoding report"); sb.AppendFormat(" Number of c-steps: {0}", flowSpec.NumCSteps); sb.AppendLine(); sb.AppendFormat(" Maximum LUT inputs: {0}", maxSelWidth); sb.AppendLine(); FlowSpec = flowSpec; var flowMap = new Dictionary <SignalRef, List <Flow> >(); var neutralFlow = flowSpec.NeutralFlow; _vcf.AddFlow(neutralFlow); for (int i = 0; i < flowSpec.NumCSteps; i++) { var pflow = flowSpec.GetFlow(i); var nflow = new ParFlow(neutralFlow); nflow.Integrate(pflow); _vcf.AddFlow(nflow); foreach (var flow in nflow.Flows) { List <Flow> flows; if (!flowMap.TryGetValue(flow.Target, out flows)) { flows = new List <Flow>(); flowMap[flow.Target] = flows; } flows.Add(flow); } } _vcf.Encode(); var startTime = DateTime.Now; var encFlows = flowMap.Values .Select((l, i) => new EncodedFlow(l, i)).ToArray(); var uncompressedMuxBits = encFlows.Sum(ef => MathExt.CeilLog2(ef.NumSymbols)); sb.AppendFormat(" Uncompressed CW: {0} MUX bits + {1} value bits", uncompressedMuxBits, _vcf.GetUncompressedValueWordWidth()); sb.AppendLine(); int numTargets = encFlows.Length; var mergeCandidates = new List <Tuple <int, int, MergedFlow> >(); var indices = new SortedSet <int>(Enumerable.Range(0, numTargets)); var curGen = (EncodedFlow[])encFlows.Clone(); bool mergedAny; var nextCandidates = new List <Tuple <int, int, MergedFlow> >(); do { foreach (int i in indices) { if (curGen[i].NumSymbols <= 1) { continue; } var upview = indices.GetViewBetween(i + 1, numTargets); foreach (int j in upview) { if (curGen[j].NumSymbols <= 1) { continue; } var mergedFlow = new MergedFlow(curGen[i], curGen[j]); mergeCandidates.Add(Tuple.Create(i, j, mergedFlow)); } } var orderedMergeCandidates = mergeCandidates.OrderByDescending(t => t.Item3.Score); var nextGen = (EncodedFlow[])curGen.Clone(); var mergedIndices = new HashSet <int>(); var mergedLowIndices = new SortedSet <int>(); var mergedHiIndices = new HashSet <int>(); mergedAny = false; foreach (var tup in orderedMergeCandidates) { Debug.Assert(tup.Item2 > tup.Item1); var mergedFlow = tup.Item3; if (mergedFlow.Score == 0.0) { break; } int selWidth = MathExt.CeilLog2(mergedFlow.NumSymbols); if (selWidth > maxSelWidth) { continue; } if (mergedIndices.Contains(tup.Item1) || mergedIndices.Contains(tup.Item2)) { continue; } mergedIndices.Add(tup.Item1); mergedIndices.Add(tup.Item2); mergedLowIndices.Add(tup.Item1); mergedHiIndices.Add(tup.Item2); indices.Remove(tup.Item2); mergedFlow.Realize(); Debug.Assert(nextGen[tup.Item1].Targets.All(t => mergedFlow.Targets.Contains(t))); Debug.Assert(nextGen[tup.Item2].Targets.All(t => mergedFlow.Targets.Contains(t))); nextGen[tup.Item1] = mergedFlow; mergedAny = true; } nextCandidates.Clear(); curGen = nextGen; mergeCandidates.Clear(); mergeCandidates.AddRange(nextCandidates); }while (mergedAny); _strings = indices.Select(i => new MicroString(curGen[i], _vcf)).ToArray(); // Verification var coveredTargets = _strings.SelectMany(s => s.Targets); var allTargets = encFlows.SelectMany(f => f.Targets); var isect0 = coveredTargets.Except(allTargets); var isect1 = allTargets.Except(coveredTargets); Debug.Assert(!isect0.Any()); Debug.Assert(!isect1.Any()); // int offset = _vcf.ValueWordWidth; int order = 0; foreach (var ms in _strings) { ms.SelOffset = offset; ms.Order = order; offset += ms.SelWidth; order++; } CWWidth = offset; var stopTime = DateTime.Now; var runTime = stopTime - startTime; sb.AppendFormat(" Compressed CW: {0} MUX bits + {1} value bits", offset - _vcf.ValueWordWidth, _vcf.ValueWordWidth); sb.AppendLine(); sb.AppendFormat(" Maximum LUT inputs: {0}", _strings.Max(s => s.SelWidth)); sb.AppendFormat(" Running time: {0} ms", runTime.TotalMilliseconds); sb.AppendLine(); sb.AppendLine(); sb.AppendLine("Number of MUX inputs; Number of occurences"); var histo = _strings.GroupBy(s => s.SelWidth) .OrderByDescending(grp => grp.Key); foreach (var grp in histo) { sb.AppendFormat("{0}; {1}", grp.Key, grp.Count()); sb.AppendLine(); } return(sb.ToString()); }