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; }
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); } } }
private void LinkPortTo(ISimulationAccess sim, Port port, Node nDesired) { Node nCurrent = null; List <Node> nRemove = null; foreach (Node n in port.Neighbors) { if (n is Port) { // ignore - this is a link to the submodule's circuit } else if (nCurrent == null) { nCurrent = n; } else { if (nRemove == null) { nRemove = new List <Node>(); } nRemove.Add(n); } } if (nRemove != null) { foreach (Node n in nRemove) { if (Debug) { Console.WriteLine(" remove link {0}-{0}", port, n); } sim.RemoveLink(new Link(port, n)); } } if (nDesired != nCurrent) { if (nCurrent != null) { if (Debug) { Console.WriteLine(" remove link {0}-{1}", port, nCurrent); } sim.RemoveLink(new Link(port, nCurrent)); } if (nDesired != null) { if (Debug) { Console.WriteLine(" add link {0}-{1}", port, nDesired); } sim.AddLink(new Link(port, nDesired)); } } }
public Value GetValueAt(ILayoutAccess layout, ISimulationAccess sim, Location loc) { layout.CheckReadAccess(); sim.CheckReadAccess(); LayoutNode sup = layout.FindNode(loc); if (nodeMap.ContainsKey(sup)) { return(sim.Get(nodeMap[sup])); } else { return(Value.X); } }
private void Clear() { Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestWriteAccess(simModel); using (xn.Start()) { foreach (Instance i in instanceMap.Values) { sim.RemoveInstance(i); } foreach (Node u in nodeMap.Values) { foreach (Link link in u.Links) { sim.RemoveLink(link); } } } }
private bool Send(PokeEventType type, IPointerEvent evnt) { if (poking != null) { Pokeable dest = poking.Component as Pokeable; Location loc = pokingLocation; MyPokeEvent pokeEvnt = new MyPokeEvent(type, evnt.X - loc.X, evnt.Y - loc.Y, evnt); dest.ProcessPokeEvent(pokeEvnt); if (pokeEvnt.pokeRejected) { return(false); } if (pokeEvnt.StateUpdate != null || pokeEvnt.repropagateRequested) { Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestWriteAccess(layoutModel.LayoutSim.SimulationModel); using (xn.Start()) { if (pokeEvnt.StateUpdate != null) { pokeEvnt.StateUpdate(new InstanceState(sim, poking)); } if (pokeEvnt.repropagateRequested) { sim.MarkInstanceDirty(poking); } } } if (pokeEvnt.pokeRejected) // may be rejected within StateUpdate { return(false); } if (pokeEvnt.viewRequested != null) { layoutModel.RequestView(pokeEvnt.viewRequested, pokeEvnt.viewSimulation); } return(true); } else { return(false); } }
private void RenewPortLinks(ILayoutAccess subLayout, ISimulationAccess sim) { IEnumerator <Port> ports = this.Ports.GetEnumerator(); IEnumerator <Component> pins = subLayout.Pins.GetEnumerator(); while (ports.MoveNext() && pins.MoveNext()) { Port compPort = ports.Current; Component pin = pins.Current; Instance pinInstance = subSimulation.GetInstance(subLayout, pin); if (pinInstance != null) { Port pinPort = null; foreach (Port tempPinPort in pinInstance.Ports) { pinPort = tempPinPort; break; } List <Link> toRemove = new List <Link>(2); foreach (Node nbr in pinPort.Neighbors) { if (nbr is Port && nbr != compPort) { toRemove.Add(new Link(pinPort, nbr)); } } foreach (Node nbr in compPort.Neighbors) { if (nbr is Port && nbr != pinPort) { toRemove.Add(new Link(compPort, nbr)); } } foreach (Link outLink in toRemove) { sim.RemoveLink(outLink); } sim.AddLink(new Link(compPort, pinPort)); } } }
protected override void HandleEventHook(InstanceEvent evnt, IInstanceState state) { SimulationModel simModel = null; if (evnt is SimulationInstanceEvent) { simModel = ((SimulationInstanceEvent)evnt).SimulationModel; } if (evnt.Type == InstanceEvent.Types.InstanceAdded) { Transaction xn = new Transaction(); ILayoutAccess subLayout = xn.RequestReadAccess(subLayoutModel); ISimulationAccess sim = xn.RequestWriteAccess(simModel); using (xn.Start()) { subSimulation = new LayoutSimulation(simModel, subLayoutModel); subSimulation.SetActivated(true); RenewPortLinks(subLayout, sim); } } else if (evnt.Type == InstanceEvent.Types.InstancePortsChanged) { if (simModel == null) { simModel = subSimulation.SimulationModel; } if (subLayoutModel == null || simModel == null) { return; } Transaction xn = new Transaction(); ILayoutAccess subLayout = xn.RequestReadAccess(subLayoutModel); ISimulationAccess sim = xn.RequestWriteAccess(simModel); using (xn.Start()) { RenewPortLinks(subLayout, sim); } } else if (evnt.Type == InstanceEvent.Types.InstanceRemoved) { subSimulation.SetActivated(false); } }
private void Run() { while (true) { Transaction xn = new Transaction(); ISimulationAccess testSim = xn.RequestReadAccess(simModel); using (xn.Start()) { while (!testSim.IsStepPending() && !stopRequested) { xn.WaitForModify(testSim, monitor, () => stopRequested); } } if (stopRequested) { break; } xn = new Transaction(); ISimulationAccess stepSim = xn.RequestWriteAccess(simModel); using (xn.Start()) { stepSim.StepSimulation(); } } }
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); }
protected override void PaintModel(IPaintbrush pb) { repainter.NotifyRepainted(); LayoutModel layoutModel = this.Layout; LayoutSimulation layoutSim = this.LayoutSim; if (layoutModel == null) { return; } if (layoutSim.LayoutModel != layoutModel) { Console.Error.WriteLine("layoutSim and layoutModel do not match"); return; } ComponentPainter ip = new ComponentPainter(pb, null); bool noHidden = hidden.Count == 0; Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestReadAccess(layoutSim.SimulationModel); ILayoutAccess layout = xn.RequestReadAccess(layoutModel); using (xn.Start()) { using (IPaintbrush pbSub = pb.Create()) { pbSub.StrokeWidth = Constants.WIRE_WIDTH; foreach (WireSegment wire in layout.Wires) { Value val0 = layoutSim.GetValueAt(layout, sim, wire.End0); pbSub.Color = Constants.GetColorFor(val0); pbSub.StrokeLine(wire.End0.X, wire.End0.Y, wire.End1.X, wire.End1.Y); } } InstanceState state = new InstanceState(sim, null); ip.InstanceState = state; foreach (Component component in layout.Components) { if (noHidden || !hidden.Contains(component)) { Location loc = component.GetLocation(layout); using (IPaintbrush pbSub = pb.Create()) { pbSub.TranslateCoordinates(loc.X, loc.Y); ip.Paintbrush = pbSub; state.Instance = layoutSim.GetInstance(layout, component); component.Paint(ip); } } } using (IPaintbrush pbSub = pb.Create()) { foreach (Location loc in WiringPoints.SolderPoints) { Value val = layoutSim.GetValueAt(layout, sim, loc); pbSub.Color = Constants.GetColorFor(val); if (noHidden || WiringPoints.IsSolderPoint(loc, hidden)) { pbSub.FillCircle(loc.X, loc.Y, Constants.SOLDER_RADIUS); } } } } }
public InstanceState(ISimulationAccess access, Instance instance) { this.access = access; this.Instance = instance; }
private void Configure(ILayoutAccess layout) { activated = true; Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestWriteAccess(simModel); if (layout == null) { layout = xn.RequestReadAccess(this.LayoutModel); } using (xn.Start()) { foreach (LayoutNode node in layout.Nodes) { if (!nodeMap.ContainsKey(node)) { nodeMap[node] = new Node(); } } foreach (Component comp in layout.Components) { if (!instanceMap.ContainsKey(comp)) { Instance instance = comp.CreateInstance(); instanceMap[comp] = instance; sim.AddInstance(instance); } } if (Debug) { Console.WriteLine("Circuit edited"); } foreach (Component comp in layout.Components) { Location compLoc = comp.GetLocation(layout); String cstr = null; Instance instance = instanceMap[comp]; IEnumerator <ConnectionPoint> conns = comp.Connections.GetEnumerator(); IEnumerator <Port> ports = instance.Ports.GetEnumerator(); int i = -1; while (conns.MoveNext() && ports.MoveNext()) { i++; ConnectionPoint conn = conns.Current; Port port = ports.Current; Location connLoc = compLoc.Translate(conn.Dx, conn.Dy); if (Debug) { if (i == 0) { cstr = String.Format("{0}[{1}]", comp.GetType().Name, compLoc.ToString()); } else { cstr = String.Format("{0," + cstr.Length + "}", ""); } Console.WriteLine(" {0}.{1}: {2} [{3}]", cstr, i, layout.FindNode(connLoc), connLoc); } LinkPortTo(sim, port, nodeMap[layout.FindNode(connLoc)]); } } } }