mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 23:06:22 -04:00
added a tunnel to connect nets
This commit is contained in:
parent
5dd2ea1ad0
commit
d76e700498
@ -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", "");
|
||||
}
|
||||
|
59
src/main/java/de/neemann/digital/draw/elements/Tunnel.java
Normal file
59
src/main/java/de/neemann/digital/draw/elements/Tunnel.java
Normal 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) {
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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()});
|
||||
|
@ -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
|
||||
|
@ -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!
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user