added a tunnel to connect nets

This commit is contained in:
hneemann 2016-04-18 13:47:52 +02:00
parent 5dd2ea1ad0
commit d76e700498
13 changed files with 283 additions and 22 deletions

View File

@ -186,4 +186,9 @@ public final class Keys {
public static final Key<String> DESCRIPTION
= new Key<>("Description", "");
/**
* A net name
*/
public static final Key<String> NETNAME
= new Key<>("NetName", "");
}

View File

@ -0,0 +1,59 @@
package de.neemann.digital.draw.elements;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import static de.neemann.digital.core.element.PinInfo.input;
/**
* Allows a tunneling of wires to make the schematic more readable then drawing
* long wires.
*
* @author hneemann
*/
public class Tunnel implements Element {
/**
* The TunnelElement description
*/
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription(Tunnel.class, input("in"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.NETNAME);
private final String label;
/**
* Creates a new instance
*
* @param attributes the attributes
*/
public Tunnel(ElementAttributes attributes) {
this.label = attributes.getLabel();
}
/**
* @return the label
*/
public String getLabel() {
return label;
}
@Override
public void setInputs(ObservableValue... inputs) throws NodeException {
}
@Override
public ObservableValue[] getOutputs() {
return new ObservableValue[0];
}
@Override
public void registerNodes(Model model) {
}
}

View File

@ -18,10 +18,10 @@ import de.neemann.digital.draw.model.NetList;
*/
public class CustomElement implements Element {
private final NetList netList;
private final Circuit circuit;
private final ElementLibrary library;
private final String name;
private NetList netList;
/**
* Creates a new custom element
@ -34,7 +34,6 @@ public class CustomElement implements Element {
this.circuit = circuit;
this.library = library;
this.name = name;
netList = new NetList(circuit.getWires());
}
/**
@ -46,6 +45,9 @@ public class CustomElement implements Element {
* @throws NodeException NodeException
*/
public ModelDescription getModelDescription() throws PinException, NodeException {
if (netList == null)
netList = new NetList(circuit);
return new ModelDescription(circuit, library, true, name, new NetList(netList));
}

View File

@ -10,6 +10,7 @@ import de.neemann.digital.core.flipflops.FlipflopT;
import de.neemann.digital.core.io.*;
import de.neemann.digital.core.memory.*;
import de.neemann.digital.core.wiring.*;
import de.neemann.digital.draw.elements.Tunnel;
import de.neemann.digital.gui.components.data.DummyElement;
import de.neemann.digital.gui.components.terminal.Terminal;
import de.neemann.digital.lang.Lang;
@ -63,6 +64,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
add(Splitter.DESCRIPTION, menu);
add(Clock.DESCRIPTION, menu);
add(Delay.DESCRIPTION, menu);
add(Tunnel.DESCRIPTION, menu);
add(Driver.DESCRIPTION, menu);
add(Reset.DESCRIPTION, menu);
add(Break.DESCRIPTION, menu);

View File

@ -54,7 +54,7 @@ public class ModelDescription implements Iterable<ModelEntry> {
* @throws NodeException NodeException
*/
public ModelDescription(Circuit circuit, ElementLibrary library, boolean readAsCustom) throws PinException, NodeException {
this(circuit, library, readAsCustom, "unknown", new NetList(circuit.getWires()));
this(circuit, library, readAsCustom, "unknown", new NetList(circuit));
}
/**

View File

@ -25,6 +25,7 @@ public class Net {
private final HashSet<Vector> points;
private final ArrayList<Pin> pins;
private final ArrayList<Wire> wires;
private final HashSet<String> labelSet;
/**
* Creates a copy of the given net
@ -35,6 +36,7 @@ public class Net {
points = toCopy.points; // no deep copy of points necessary
wires = null; // wires not needed
pins = new ArrayList<>(toCopy.pins); // Pins are changed so create a deep copy
labelSet = new HashSet<>(toCopy.labelSet); //ToDo copy necessary?
}
/**
@ -49,6 +51,7 @@ public class Net {
pins = new ArrayList<>();
wires = new ArrayList<>();
wires.add(w);
labelSet = new HashSet<>();
}
/**
@ -86,9 +89,10 @@ public class Net {
*
* @param changedNet the net to add
*/
public void addAllPointsFrom(Net changedNet) {
void addAllPointsFrom(Net changedNet) {
points.addAll(changedNet.points);
wires.addAll(changedNet.wires);
labelSet.addAll(changedNet.labelSet);
}
/**
@ -187,4 +191,34 @@ public class Net {
if (!pins.remove(p))
throw new PinException(Lang.get("err_pinNotPresent"), this);
}
/**
* Adds a label this this net
*
* @param label the label to add
*/
public void addLabel(String label) {
labelSet.add(label);
}
/**
* Returns true if the given net has at least one same net label.
*
* @param net the other net
* @return true if same net
*/
public boolean matchesLabel(Net net) {
for (String l : labelSet) {
if (net.labelSet.contains(l))
return true;
}
return false;
}
@Override
public String toString() {
return "Net{" +
"labelSet=" + labelSet +
'}';
}
}

View File

@ -1,12 +1,12 @@
package de.neemann.digital.draw.model;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.*;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.lang.Lang;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Holds all the nets in a circuit
@ -18,14 +18,42 @@ public class NetList implements Iterable<Net> {
private final ArrayList<Net> netList;
/**
* Creates a net list from the given wires
* Creates a net list from the given circuit
*
* @param wires the wires
* @param circuit the circuit
* @throws PinException PinException
*/
public NetList(List<Wire> wires) {
public NetList(Circuit circuit) throws PinException {
netList = new ArrayList<>();
for (Wire w : wires)
for (Wire w : circuit.getWires())
add(w);
for (VisualElement ve : circuit.getElements())
if (ve.getElementName().equals(Tunnel.DESCRIPTION.getName())) {
Vector pos = ve.getPos();
Net found = null;
for (Net n : netList)
if (n.contains(pos))
found = n;
String label = ve.getElementAttributes().get(Keys.NETNAME).trim();
if (found == null)
throw new PinException(Lang.get("err_labelNotConnectedToNet_N", label), ve);
found.addLabel(label);
}
mergeLabels();
}
private void mergeLabels() {
for (int i = 0; i < netList.size() - 1; i++)
for (int j = i + 1; j < netList.size(); j++)
if (netList.get(i).matchesLabel(netList.get(j))) {
netList.get(i).addAllPointsFrom(netList.get(j));
netList.remove(j);
j--;
}
}
/**
@ -49,7 +77,7 @@ public class NetList implements Iterable<Net> {
}
/**
* Adds a pin to tis net list
* Adds a pin to this net list
*
* @param pin the pin to add
*/

View File

@ -10,6 +10,7 @@ import de.neemann.digital.core.io.*;
import de.neemann.digital.core.memory.RAMDualPort;
import de.neemann.digital.core.memory.RAMSinglePort;
import de.neemann.digital.core.wiring.*;
import de.neemann.digital.draw.elements.Tunnel;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.gui.LibrarySelector;
import de.neemann.digital.gui.components.data.DummyElement;
@ -67,6 +68,7 @@ public final class ShapeFactory {
map.put(Splitter.DESCRIPTION.getName(), SplitterShape::new);
map.put(Driver.DESCRIPTION.getName(), DriverShape::new);
map.put(Tunnel.DESCRIPTION.getName(), TunnelShape::new);
map.put(DummyElement.TEXTDESCRIPTION.getName(), TextShape::new);
}

View File

@ -0,0 +1,56 @@
package de.neemann.digital.draw.shapes;
import de.neemann.digital.core.Observer;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.PinDescription;
import de.neemann.digital.draw.elements.IOState;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.Pins;
import de.neemann.digital.draw.graphics.*;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
/**
* The Tunnel shape
*
* @author hneemann
*/
public class TunnelShape implements Shape {
private final PinDescription input;
private final String label;
/**
* Creates a new instance
*
* @param attr the attributes
* @param inputs the inputs
* @param outputs the outputs
*/
public TunnelShape(ElementAttributes attr, PinDescription[] inputs, PinDescription[] outputs) {
input = inputs[0];
label = attr.get(Keys.NETNAME);
}
@Override
public Pins getPins() {
return new Pins().add(new Pin(new Vector(0, 0), input));
}
@Override
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
return null;
}
@Override
public void drawTo(Graphic gr, boolean highLight) {
gr.drawPolygon(new Polygon(true)
.add(0, 0)
.add(SIZE, SIZE2)
.add(SIZE, -SIZE2), Style.NORMAL);
Vector pos = new Vector(SIZE + SIZE2, 0);
gr.drawText(pos, pos.add(1, 0), label, Orientation.LEFTCENTER, Style.SHAPE_PIN);
}
}

View File

@ -492,6 +492,8 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
circuitComponent.addHighLighted(e.getVisualElement());
if (e.getNet() != null)
circuitComponent.addHighLighted(e.getNet().getWires());
else if (e.getVisualElement() != null)
circuitComponent.addHighLighted(e.getVisualElement());
} else if (cause instanceof BurnException) {
BurnException e = (BurnException) cause;
circuitComponent.addHighLightedWires(new ObservableValue[]{e.getValue()});

View File

@ -46,6 +46,8 @@ key_maxStepCount=Maximale Messpunktezahl
key_microStep=Zeige Einzelgatterschritte
key_isHighZ=Eingang kann hochohmig sein
key_Description=Beschreibung
key_NetName=Netzname
key_NetName_tt=Alle Netze mit identischem Namen werden verbunden.
elem_And=Und
elem_NAnd=Nicht Und
@ -164,6 +166,7 @@ err_readOfHighZ=Lesen einer hochohmigen Leitung
err_notAllOutputsSameBits=Es haben nicht alle Ausg\u00E4nge die gleiche Bitbreite
err_notAllOutputsSupportHighZ=Wenn mehrere Ausg\u00E4nge verbunden sind, m\u00FCssen alle Ausg\u00E4nge Tri-State Ausg\u00E4nge sein
err_breakTimeOut=Nach {0} Zyklen ist kein Break aufgetreten
err_labelNotConnectedToNet_N=Ein Tunnel {0} ist nicht verbunden!
attr_dialogTitle=Eigenschaften
msg_errorEditingValue=Fehler bei der Eingabe eines Wertes

View File

@ -41,6 +41,8 @@ key_microStep=Show single gate steps
key_isHighZ=Is three-state input
key_runRealTime=Start real time clock
key_Description=Description
key_NetName=Netname
key_NetName_tt=All nets with identical name are connected together.
elem_And=And
elem_NAnd=NAnd
@ -248,3 +250,4 @@ elem_Decoder_tt=One selectable output line is high, all other outputs are low.
elem_Decode_pin_sel=This input selects the enabled output
elem_Text_tt=Shows a text in the circuit
key_Default_tt=Is set if the model is started
err_labelNotConnectedToNet_N=A tunnel {0} is not connected!

View File

@ -1,26 +1,91 @@
package de.neemann.digital.draw.model;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.draw.graphics.Vector;
import junit.framework.TestCase;
import java.util.ArrayList;
/**
* @author hneemann
*/
public class NetListTest extends TestCase {
public void testSimple() throws Exception {
ArrayList<Wire> w = new ArrayList<>();
Circuit c = new Circuit();
w.add(new Wire(new Vector(1, 1), new Vector(1, 2)));
w.add(new Wire(new Vector(2, 1), new Vector(2, 2)));
w.add(new Wire(new Vector(1, 2), new Vector(2, 2)));
w.add(new Wire(new Vector(1, 1), new Vector(2, 1)));
c.add(new Wire(new Vector(1, 1), new Vector(1, 2)));
c.add(new Wire(new Vector(2, 1), new Vector(2, 2)));
c.add(new Wire(new Vector(1, 2), new Vector(2, 2)));
c.add(new Wire(new Vector(1, 1), new Vector(2, 1)));
NetList ns = new NetList(w);
NetList ns = new NetList(c);
assertEquals(1, ns.size());
}
}
private void addTunnel(Circuit c, Vector pos, String name) {
VisualElement ve = new VisualElement("Tunnel")
.setPos(pos);
ve.getElementAttributes().set(Keys.NETNAME, name);
c.add(ve);
}
public void testTunnel() throws Exception {
Circuit c = new Circuit();
c.add(new Wire(new Vector(1, 1), new Vector(2, 1)));
addTunnel(c, new Vector(2, 1), "A");
c.add(new Wire(new Vector(3, 1), new Vector(4, 1)));
addTunnel(c, new Vector(3, 1), "A");
NetList ns = new NetList(c);
assertEquals(1, ns.size());
}
public void testTunnel2() throws Exception {
Circuit c = new Circuit();
c.add(new Wire(new Vector(1, 1), new Vector(2, 1)));
addTunnel(c, new Vector(2, 1), "A");
c.add(new Wire(new Vector(3, 1), new Vector(4, 1)));
addTunnel(c, new Vector(3, 1), "A");
c.add(new Wire(new Vector(1, 4), new Vector(2, 4)));
addTunnel(c, new Vector(2, 4), "B");
c.add(new Wire(new Vector(3, 4), new Vector(4, 4)));
addTunnel(c, new Vector(3, 4), "B");
NetList ns = new NetList(c);
assertEquals(2, ns.size());
}
public void testTunnel3() throws Exception {
Circuit c = new Circuit();
c.add(new Wire(new Vector(1, 1), new Vector(2, 1)));
addTunnel(c, new Vector(2, 1), "A");
c.add(new Wire(new Vector(3, 1), new Vector(4, 1)));
addTunnel(c, new Vector(3, 1), "A");
addTunnel(c, new Vector(4, 1), "C");
c.add(new Wire(new Vector(1, 4), new Vector(2, 4)));
addTunnel(c, new Vector(2, 4), "B");
addTunnel(c, new Vector(1, 4), "C");
c.add(new Wire(new Vector(3, 4), new Vector(4, 4)));
addTunnel(c, new Vector(3, 4), "B");
NetList ns = new NetList(c);
assertEquals(1, ns.size());
}
}