/// <summary> /// Adds an aggregate dataflow describing the neutral (default) dataflow for all specified targets. /// </summary> /// <param name="pflow">the neutral dataflow as aggregate dataflow</param> public void AddNeutral(ParFlow pflow) { foreach (Flow flow in pflow.Flows) { _neutral.Add(flow); } }
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); }
/// <summary> /// Adds an aggregate dataflow to the flow matrix at specified c-step /// </summary> /// <param name="cstep">c-step when the dataflow is active</param> /// <param name="pflow">the aggregate dataflow to add</param> public void Add(int cstep, ParFlow pflow) { foreach (Flow flow in pflow.Flows) { Add(cstep, flow); } }
public StdLogicVector Encode(int cstep, ParFlow cstepFlow) { var cword = StdLogicVector._0s(CWWidth); ParFlow allFlow = new ParFlow(FlowSpec.NeutralFlow); allFlow.Integrate(cstepFlow); Encode(cstep, allFlow, ref cword); return(cword); }
public void AddFlow(ParFlow pflow) { var vflows = pflow.Flows.Where(f => f is ValueFlow && !FlowMatrix.IsDontCareFlow(f)); _flowList.Add(new ParFlow(vflows)); foreach (var f in vflows) { var vflow = (ValueFlow)f; int width = Marshal.SerializeForHW(vflow.Value).Size; _widthMap[f.Target] = width; } }
private void Encode(int cstep, ParFlow pflow, ref StdLogicVector cword) { foreach (var ms in _strings) { var projflow = new ParFlow(); foreach (var target in ms.Targets) { var flow = pflow.LookupTarget(target); if (flow != null) { projflow.Add(flow); } } ms.Encode(cstep, projflow, ref cword); } }
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(); }
public EncodedFlow(List <Flow> flows, int order) { Contract.Requires(flows != null && flows.Any()); Contract.Requires(flows.All(f => f.Target.Equals(flows.First().Target))); Targets = new SignalRef[] { flows.First().Target }; EncodedSymbols = new int[flows.Count]; Order = order; _bwdEnc = new List <ParFlow>(); int i = 0; foreach (var flow in flows) { int sym = 0; if (!FlowMatrix.IsDontCareFlow(flow)) { var vflow = flow as ValueFlow; Flow cflow; if (vflow != null) { cflow = FlowMatrix.AsDontCareFlow(vflow); } else { cflow = flow; } var cpflow = new ParFlow(new Flow[] { cflow }); if (!_fwdEnc.TryGetValue(cpflow, out sym)) { sym = ++NumSymbols; _fwdEnc[cpflow] = sym; _bwdEnc.Add(new ParFlow(new Flow[] { cflow })); } } EncodedSymbols[i] = sym; i++; } if (_bwdEnc.Count == 0) { var dummy = new ParFlow(); _bwdEnc.Add(dummy); _fwdEnc[dummy] = 1; NumSymbols = 1; } }
public EncodedFlow(List<Flow> flows, int order) { Contract.Requires(flows != null && flows.Any()); Contract.Requires(flows.All(f => f.Target.Equals(flows.First().Target))); Targets = new SignalRef[] { flows.First().Target }; EncodedSymbols = new int[flows.Count]; Order = order; _bwdEnc = new List<ParFlow>(); int i = 0; foreach (var flow in flows) { int sym = 0; if (!FlowMatrix.IsDontCareFlow(flow)) { var vflow = flow as ValueFlow; Flow cflow; if (vflow != null) cflow = FlowMatrix.AsDontCareFlow(vflow); else cflow = flow; var cpflow = new ParFlow(new Flow[] { cflow }); if (!_fwdEnc.TryGetValue(cpflow, out sym)) { sym = ++NumSymbols; _fwdEnc[cpflow] = sym; _bwdEnc.Add(new ParFlow(new Flow[] { cflow })); } } EncodedSymbols[i] = sym; i++; } if (_bwdEnc.Count == 0) { var dummy = new ParFlow(); _bwdEnc.Add(dummy); _fwdEnc[dummy] = 1; NumSymbols = 1; } }
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(); }
public IEnumerable <ParFlow> ToFlow(int numCsteps, ParFlow neutralFlow, bool[,] pipeEnMatrix) { int muxCount = _pipeInSignals.Count; int[,] flowMatrix = new int[numCsteps, muxCount]; // 1st pass: set some arbitrary MUX selection for (int i = 0; i < numCsteps; i++) { for (int j = 0; j < muxCount; j++) { if (_preds[j].Any()) { flowMatrix[i, j] = _preds[j].First(); } else { flowMatrix[i, j] = -1; } } } // 2nd pass: reset MUX selection whenever neutral flow requires // some value transfer which is not "don't care" foreach (var flow in neutralFlow.Flows) { if (FlowMatrix.IsDontCareFlow(flow) || !_signal2Idx.IsCached(flow.Target)) { continue; } int idx = _signal2Idx[flow.Target]; for (int i = 0; i < numCsteps; i++) { flowMatrix[i, idx] = -1; } } // 3rd pass: transfer MUX reservations to matrix for (int i = 0; i < _resTable.Count; i++) { var rmap = _resTable[i]; var pi = _pipes[i]; foreach (var kvp in rmap) { flowMatrix[kvp.Key + pi.delay, pi.sink] = i; } } var pipeen = pipeEnMatrix; // last pass: convert to flows for (int i = 0; i < numCsteps; i++) { var flows = new List <Flow>(); for (int j = 0; j < muxCount; j++) { int k = flowMatrix[i, j]; if (k >= 0) { flows.Add( new SignalFlow( _pipeOutSignals[k].ToSignalRef(SignalRef.EReferencedProperty.Cur), _pipeInSignals[j].ToSignalRef(SignalRef.EReferencedProperty.Next))); } } for (int pipe = 0; pipe < _pipes.Count; pipe++) { if (!_pipes[pipe].useEn) { continue; } flows.Add( new ValueFlow( pipeen[i, pipe] ? StdLogic._1 : StdLogic._0, _pipeEnSignals[pipe].ToSignalRef(SignalRef.EReferencedProperty.Next))); } yield return(new ParFlow(flows)); } }
/// <summary> /// Adds an aggregate dataflow describing the neutral (default) dataflow for all specified targets. /// </summary> /// <param name="pflow">the neutral dataflow as aggregate dataflow</param> public void AddNeutral(ParFlow pflow) { foreach (Flow flow in pflow.Flows) _neutral.Add(flow); }
/// <summary> /// Adds an aggregate dataflow to the flow matrix at specified c-step /// </summary> /// <param name="cstep">c-step when the dataflow is active</param> /// <param name="pflow">the aggregate dataflow to add</param> public void Add(int cstep, ParFlow pflow) { foreach (Flow flow in pflow.Flows) Add(cstep, flow); }
public StdLogicVector Encode(int cstep, ParFlow cstepFlow) { var cword = StdLogicVector._0s(CWWidth); ParFlow allFlow = new ParFlow(FlowSpec.NeutralFlow); allFlow.Integrate(cstepFlow); Encode(cstep, allFlow, ref cword); return cword; }
private void Encode(int cstep, ParFlow pflow, ref StdLogicVector cword) { foreach (var ms in _strings) { var projflow = new ParFlow(); foreach (var target in ms.Targets) { var flow = pflow.LookupTarget(target); if (flow != null) projflow.Add(flow); } ms.Encode(cstep, projflow, ref cword); } }
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()); }
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 void Realize() { _bwdEnc = new List<ParFlow>(); int sym; for (sym = 0; sym < _encMap0.Length; sym++) { int sym0 = _encMap0[sym]; ParFlow sym0Flow; if (sym0 == 0) sym0 = 1; sym0Flow = _encFlow0.BwdEnc[sym0 - 1]; int sym1 = _encMap1[sym]; ParFlow sym1Flow; if (sym1 == 0) sym1 = 1; sym1Flow = _encFlow1.BwdEnc[sym1 - 1]; var pflow = new ParFlow(); pflow.Integrate(sym0Flow); pflow.Integrate(sym1Flow); _bwdEnc.Add(pflow); } sym = 0; foreach (var pflow in _bwdEnc) { _fwdEnc[pflow] = ++sym; } // Verify result for (int i = 0; i < EncodedSymbols.Length; i++) { sym = EncodedSymbols[i]; int sym0 = _encFlow0.EncodedSymbols[i]; int sym1 = _encFlow1.EncodedSymbols[i]; if (sym == 0) { Debug.Assert(sym0 == 0 && sym1 == 0); continue; } if (sym0 != 0) { var pflow = _encFlow0.BwdEnc[sym0 - 1]; var mflow = BwdEnc[sym - 1]; foreach (var flow in pflow.Flows) { Debug.Assert(mflow.LookupTarget(flow.Target).Equals(flow)); } } if (sym1 != 0) { var pflow = _encFlow1.BwdEnc[sym1 - 1]; var mflow = BwdEnc[sym - 1]; foreach (var flow in pflow.Flows) { Debug.Assert(mflow.LookupTarget(flow.Target).Equals(flow)); } } } }
public void Realize() { _bwdEnc = new List <ParFlow>(); int sym; for (sym = 0; sym < _encMap0.Length; sym++) { int sym0 = _encMap0[sym]; ParFlow sym0Flow; if (sym0 == 0) { sym0 = 1; } sym0Flow = _encFlow0.BwdEnc[sym0 - 1]; int sym1 = _encMap1[sym]; ParFlow sym1Flow; if (sym1 == 0) { sym1 = 1; } sym1Flow = _encFlow1.BwdEnc[sym1 - 1]; var pflow = new ParFlow(); pflow.Integrate(sym0Flow); pflow.Integrate(sym1Flow); _bwdEnc.Add(pflow); } sym = 0; foreach (var pflow in _bwdEnc) { _fwdEnc[pflow] = ++sym; } // Verify result for (int i = 0; i < EncodedSymbols.Length; i++) { sym = EncodedSymbols[i]; int sym0 = _encFlow0.EncodedSymbols[i]; int sym1 = _encFlow1.EncodedSymbols[i]; if (sym == 0) { Debug.Assert(sym0 == 0 && sym1 == 0); continue; } if (sym0 != 0) { var pflow = _encFlow0.BwdEnc[sym0 - 1]; var mflow = BwdEnc[sym - 1]; foreach (var flow in pflow.Flows) { Debug.Assert(mflow.LookupTarget(flow.Target).Equals(flow)); } } if (sym1 != 0) { var pflow = _encFlow1.BwdEnc[sym1 - 1]; var mflow = BwdEnc[sym - 1]; foreach (var flow in pflow.Flows) { Debug.Assert(mflow.LookupTarget(flow.Target).Equals(flow)); } } } }