/// <summary> /// Replaces all value-flows transferring don't-care values by real values. /// </summary> /// <remarks> /// The semantics of the don't-care symbol admit any such symbol to be replaced with any other symbol, e.g. '0' or '1' /// without changing the behavior. However, if we blindly replace any don't care symbol with - let's say - logical zeroes, /// we won't perform optimally, since we might introduce unnecessary multiplexers. Therefore, the method first tries to /// find existing non-don't-care value-flows as suitable replacement candidates. Only if no such is found, it arbitrarily /// chooses to replace don't-cares with logical zeroes. /// </remarks> public void ReplaceDontCares() { var picks = new Dictionary <SignalRef, Flow>(); foreach (var target in FlowTargets) { Flow pick = GetFlowsTo(target) .Where(f => !IsDontCareFlow(f)) .FirstOrDefault(); if (pick == null) { ValueFlow vflow = (ValueFlow)GetFlowsTo(target).First(); StdLogicVector data = (StdLogicVector)vflow.Value; pick = new ValueFlow(StdLogicVector._0s(data.Size), target); } picks[target] = pick; } var allGraphs = _graphs.Concat(Enumerable.Repeat(_neutral, 1)); foreach (FlowGraph g in allGraphs) { var pflow = g.ToFlow(); foreach (Flow flow in pflow.Flows) { if (IsDontCareFlow(flow)) { Flow pick = picks[flow.Target]; g.Add(pick); } } } }
/// <summary> /// Replaces the data symbol of a value-flow with the specified symbol. /// If the old data symbol is a logic vector, the specified symbol is replicated to a vector. /// </summary> /// <param name="vflow">a value-flow</param> /// <param name="symbol">replacement symbol</param> /// <returns>new value-flow - same target, but different data symbol</returns> public static ValueFlow AsDontCareFlow(ValueFlow vflow, StdLogic symbol) { StdLogicVector?slvdata = vflow.Value as StdLogicVector?; StdLogic? sldata = vflow.Value as StdLogic?; if (slvdata.HasValue) { return(new ValueFlow(StdLogicVector.AllSame(symbol, slvdata.Value.Size), vflow.Target)); } if (sldata.HasValue) { return(new ValueFlow(symbol, vflow.Target)); } return(new ValueFlow(StdLogicVector.AllSame(symbol, Marshal.SerializeForHW(vflow.Value).Size), vflow.Target)); }
/// <summary> /// Replaces any don't-care symbol with the high-impedance symbol. /// </summary> public void ReplaceDontCaresByTriStates() { var allGraphs = _graphs.Concat(Enumerable.Repeat(_neutral, 1)); foreach (FlowGraph g in allGraphs) { var pflow = g.ToFlow(); foreach (Flow flow in pflow.Flows) { if (IsDontCareFlow(flow)) { var oflow = flow as ValueFlow; var slv = (StdLogicVector)oflow.Value; var zslv = StdLogicVector.Zs(slv.Size); var nflow = new ValueFlow(zslv, flow.Target); g.Add(nflow); } } } }
/// <summary> /// Checks whether a given dataflow transfers the don't care literal to its destination. /// </summary> /// <param name="flow">a dataflow</param> public static bool IsDontCareFlow(Flow flow) { ValueFlow vflow = flow as ValueFlow; if (vflow == null) { return(false); } StdLogicVector?slvdata = vflow.Value as StdLogicVector?; StdLogic? sldata = vflow.Value as StdLogic?; if (slvdata.HasValue) { return(slvdata.Value.Equals(StdLogicVector.DCs(slvdata.Value.Size))); } if (sldata.HasValue) { return(sldata.Value.Equals(StdLogic.DC)); } return(false); }
public void Transitize() { Queue <Flow> q = new Queue <Flow>(_flows.Values); // DEBUG only // var copy = new List<KeyValuePair<SignalBase, Flow>>(_flows); while (q.Any()) { var flow = q.Dequeue(); SignalFlow sflow = flow as SignalFlow; if (sflow != null) { Flow trflow; if (_flows.TryGetValue(sflow.Source, out trflow)) { SignalFlow strflow = trflow as SignalFlow; if (strflow != null) { trflow = new SignalFlow(strflow.Source, sflow.Target); } ValueFlow vtrflow = trflow as ValueFlow; if (vtrflow != null) { trflow = new ValueFlow(vtrflow.Value, sflow.Target); } _flows[sflow.Target] = trflow; if (trflow.Equals(sflow)) { throw new InvalidOperationException("Cyclic dataflow"); } q.Enqueue(trflow); } } } }
/// <summary> /// Replaces the data symbol of a value-flow with the don't care symbol /// </summary> /// <param name="vflow">a value-flow</param> /// <returns>new value-flow - same target, but with don't care symbol</returns> public static ValueFlow AsDontCareFlow(ValueFlow vflow) { return(AsDontCareFlow(vflow, StdLogic.DC)); }
public void Transitize() { Queue<Flow> q = new Queue<Flow>(_flows.Values); // DEBUG only // var copy = new List<KeyValuePair<SignalBase, Flow>>(_flows); while (q.Any()) { var flow = q.Dequeue(); SignalFlow sflow = flow as SignalFlow; if (sflow != null) { Flow trflow; if (_flows.TryGetValue(sflow.Source, out trflow)) { SignalFlow strflow = trflow as SignalFlow; if (strflow != null) { trflow = new SignalFlow(strflow.Source, sflow.Target); } ValueFlow vtrflow = trflow as ValueFlow; if (vtrflow != null) { trflow = new ValueFlow(vtrflow.Value, sflow.Target); } _flows[sflow.Target] = trflow; if (trflow.Equals(sflow)) throw new InvalidOperationException("Cyclic dataflow"); q.Enqueue(trflow); } } } }
/// <summary> /// Replaces all value-flows transferring don't-care values by real values. /// </summary> /// <remarks> /// The semantics of the don't-care symbol admit any such symbol to be replaced with any other symbol, e.g. '0' or '1' /// without changing the behavior. However, if we blindly replace any don't care symbol with - let's say - logical zeroes, /// we won't perform optimally, since we might introduce unnecessary multiplexers. Therefore, the method first tries to /// find existing non-don't-care value-flows as suitable replacement candidates. Only if no such is found, it arbitrarily /// chooses to replace don't-cares with logical zeroes. /// </remarks> public void ReplaceDontCares() { var picks = new Dictionary<SignalRef, Flow>(); foreach (var target in FlowTargets) { Flow pick = GetFlowsTo(target) .Where(f => !IsDontCareFlow(f)) .FirstOrDefault(); if (pick == null) { ValueFlow vflow = (ValueFlow)GetFlowsTo(target).First(); StdLogicVector data = (StdLogicVector)vflow.Value; pick = new ValueFlow(StdLogicVector._0s(data.Size), target); } picks[target] = pick; } var allGraphs = _graphs.Concat(Enumerable.Repeat(_neutral, 1)); foreach (FlowGraph g in allGraphs) { var pflow = g.ToFlow(); foreach (Flow flow in pflow.Flows) { if (IsDontCareFlow(flow)) { Flow pick = picks[flow.Target]; g.Add(pick); } } } }
/// <summary> /// Replaces the data symbol of a value-flow with the don't care symbol /// </summary> /// <param name="vflow">a value-flow</param> /// <returns>new value-flow - same target, but with don't care symbol</returns> public static ValueFlow AsDontCareFlow(ValueFlow vflow) { return AsDontCareFlow(vflow, StdLogic.DC); }
/// <summary> /// Replaces the data symbol of a value-flow with the specified symbol. /// If the old data symbol is a logic vector, the specified symbol is replicated to a vector. /// </summary> /// <param name="vflow">a value-flow</param> /// <param name="symbol">replacement symbol</param> /// <returns>new value-flow - same target, but different data symbol</returns> public static ValueFlow AsDontCareFlow(ValueFlow vflow, StdLogic symbol) { StdLogicVector? slvdata = vflow.Value as StdLogicVector?; StdLogic? sldata = vflow.Value as StdLogic?; if (slvdata.HasValue) return new ValueFlow(StdLogicVector.AllSame(symbol, slvdata.Value.Size), vflow.Target); if (sldata.HasValue) return new ValueFlow(symbol, vflow.Target); return new ValueFlow(StdLogicVector.AllSame(symbol, Marshal.SerializeForHW(vflow.Value).Size), vflow.Target); }