private static void ProcessPortsAndSetSubnets(SimulationModel.Key key, Subnet net) { List <Port> readers = new List <Port>(); List <Port> drivers = new List <Port>(); foreach (Node node in net.nodes) { node.SetSubnet(key, net); Port port = node as Port; if (port != null) { if (port.IsInput) { readers.Add(port); } if (port.IsOutput) { drivers.Add(port); } } } readers.TrimExcess(); drivers.TrimExcess(); net.readers = readers; net.drivers = drivers; }
public void Step(SimulationModel.Key key, ISimulationAccess access) { long now = curTime + 1; curTime = now; if (Debug) { Console.WriteLine("step simulation {0}", now); } ClearDirty(key, access); while (events.Count > 0 && events.Peek().when == now) { SetEvent evnt = events.Dequeue(); Port p = evnt.port; Value cur = p.GetDrivenValue(key); if (Debug) { Console.WriteLine(" {0}: drive {1} onto {2}, mark {3}", evnt.when, evnt.value, evnt.port, p.Subnet); } if (!cur.Equals(evnt.value)) { p.SetDrivenValue(key, evnt.value); dirtyNets.Add(p.Subnet); } } ClearDirty(key, access); anyDirty = events.Count > 0 || dirtyNets.Count > 0 || dirtyInstances.Count > 0; }
public void SetValue(SimulationModel.Key key, Value value) { if (key == null) { throw new ArgumentException("key needed"); } this.value = value; }
public Value GetValue(SimulationModel.Key key) { if (key == null) { throw new ArgumentException("key needed"); } return(value); }
private void ClearDirty(SimulationModel.Key key, ISimulationAccess access) { HashSet <Subnet> nets = dirtyNets; HashSet <Instance> instances = dirtyInstances; if (nets != null && nets.Count > 0) { dirtyNets = new HashSet <Subnet>(); foreach (Subnet net in nets) { if (Debug) { Console.Write(" net {0} /", net); } Value v = null; foreach (Port p in net.Drivers) { Value u = p.GetDrivenValue(key); if (Debug) { Console.Write("{0}/", u); } v = v == null ? u : v.Resolve(u); } if (Debug) { Console.WriteLine("-> {0}", v); } if (v == null) { int w = net.Width; v = Value.Create(Value.U, w == 0 ? 1 : w); } net.SetValue(key, v); foreach (Port p in net.Readers) { instances.Add(p.Instance); } } } if (instances != null && instances.Count > 0) { InstanceEvent evnt = new InstanceEvent(InstanceEvent.Types.InstanceDirty); InstanceState iState = new InstanceState(access, null); dirtyInstances = new HashSet <Instance>(); foreach (Instance instance in instances) { if (Debug) { Console.WriteLine(" propagate instance {0}", instance); } iState.Instance = instance; instance.HandleEvent(evnt, iState); } } }
public void SetTempSubnet(SimulationModel.Key key, Subnet value) { if (key == null) { throw new InvalidOperationException("need key"); } else { this.TempSubnet = value; } }
public void AddLink(SimulationModel.Key key, Link value) { if (key == null) { throw new InvalidOperationException("need key"); } else { List <Link> links = this.links; if (links == EmptyLinks) { links = new List <Link>(); this.links = links; this.linksView = links.AsReadOnly(); } links.Add(value); } }
public void AddToUseCount(SimulationModel.Key key, int delta) { if (key == null) { throw new InvalidOperationException("need key"); } else { int newVal = baseUseCount + delta; if (newVal < 0) { baseUseCount = 0; throw new ArgumentException("count cannot go negative"); } else { baseUseCount = newVal; } } }
public bool RemoveLink(SimulationModel.Key key, Link value) { if (key == null) { throw new InvalidOperationException("need key"); } else { List <Link> links = this.links; bool removed = links.Remove(value); if (removed) { if (links.Count == 0) { this.links = EmptyLinks; this.linksView = EmptyLinksView; } } return(removed); } }
private static Subnet FindSubnetFrom(SimulationModel.Key key, Node start) { int id = lastIdAllocated + 1; lastIdAllocated = id; Subnet net = new Subnet(id); List <Node> found = net.nodes; start.SetTempSubnet(key, net); found.Add(start); for (int i = 0; i < found.Count; i++) { Node u = found[i]; foreach (Node v in u.Neighbors) { if (v.TempSubnet == null) { v.SetTempSubnet(key, net); found.Add(v); } } } return(net); }
public static List <Subnet> UpdateNets(SimulationModel.Key key, ISimulationAccess model, List <Subnet> oldNets) { if (key == null) { throw new ArgumentException("key needed"); } if (Debug) { Console.WriteLine("Update subnets"); } foreach (Node node in model.Nodes) { node.SetTempSubnet(key, null); } List <Subnet> sortedNets = new List <Subnet>(oldNets); sortedNets.Sort((n0, n1) => n1.nodes.Count - n0.nodes.Count); List <Subnet> allNewNets = new List <Subnet>(); foreach (Subnet oldNet in sortedNets) { List <Subnet> newNets = new List <Subnet>(); int largestSize = 0; Subnet largestNet = null; foreach (Node node in oldNet.nodes) { if (node.TempSubnet == null) { Subnet net = FindSubnetFrom(key, node); newNets.Add(net); int netSize = net.nodes.Count; if (netSize > largestSize) { largestSize = netSize; largestNet = net; } } } if (largestNet == null) { // no nets identified, so nothing to do if (Debug) { Console.WriteLine(" {0} deleted", oldNet); } } else if (newNets.Count == 1 && EqualsListsShallow(oldNet.nodes, newNets[0].nodes)) { if (Debug) { Console.WriteLine(" {0} unchanged: drivers {1} readers {2} nodes {3}", oldNet, ",".JoinObjectStrings(oldNet.drivers), ",".JoinObjectStrings(oldNet.readers), ",".JoinObjectStrings(oldNet.nodes)); } allNewNets.Add(oldNet); // just keep the old net, since they're identical } else { oldNet.nodes = largestNet.nodes; foreach (Subnet rawNet in newNets) { Subnet newNet = rawNet == largestNet ? oldNet : rawNet; allNewNets.Add(newNet); ProcessPortsAndSetSubnets(key, newNet); key.Engine.AddDirtyNet(newNet); if (Debug) { Console.WriteLine(" {0} to {1}: drivers {2} readers {3} nodes {4}", oldNet, newNet, ",".JoinObjectStrings(newNet.drivers), ",".JoinObjectStrings(newNet.readers), ",".JoinObjectStrings(newNet.nodes)); } } } } foreach (Node node in model.Nodes) { if (node.TempSubnet == null) { Subnet net = FindSubnetFrom(key, node); allNewNets.Add(net); ProcessPortsAndSetSubnets(key, net); if (Debug) { Console.WriteLine("dflt net {0}: drivers {1}, readers {2}, nodes {3}", net, ",".JoinObjectStrings(net.drivers), ",".JoinObjectStrings(net.readers), ",".JoinObjectStrings(net.nodes)); } } } return(allNewNets); }