mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-24 04:42:51 -04:00
Merge branch 'pinControl'
This commit is contained in:
commit
bd80639035
83
src/main/java/de/neemann/digital/core/io/PinControl.java
Normal file
83
src/main/java/de/neemann/digital/core/io/PinControl.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.core.io;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Node;
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
import de.neemann.digital.core.ObservableValues;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pin control logic
|
||||||
|
*/
|
||||||
|
public class PinControl extends Node implements Element {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of the pin control logic
|
||||||
|
*/
|
||||||
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(PinControl.class, input("wr"), input("oe"))
|
||||||
|
.addAttribute(Keys.ROTATE)
|
||||||
|
.addAttribute(Keys.BITS)
|
||||||
|
.addAttribute(Keys.MIRROR);
|
||||||
|
|
||||||
|
private final int bits;
|
||||||
|
private final ObservableValue rdValue;
|
||||||
|
private final ObservableValue outWriteValue;
|
||||||
|
private ObservableValue wrValue;
|
||||||
|
private ObservableValue oeValue;
|
||||||
|
private ObservableValue outReadValue;
|
||||||
|
private long wr;
|
||||||
|
private boolean oe;
|
||||||
|
private long outRead;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param attr the elements attributes
|
||||||
|
*/
|
||||||
|
public PinControl(ElementAttributes attr) {
|
||||||
|
bits = attr.getBits();
|
||||||
|
rdValue = new ObservableValue("rd", bits).setPinDescription(DESCRIPTION);
|
||||||
|
outWriteValue = new ObservableValue("pin", bits).setPinDescription(DESCRIPTION).setBidirectional();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||||
|
wrValue = inputs.get(0).addObserverToValue(this).checkBits(bits, this);
|
||||||
|
oeValue = inputs.get(1).addObserverToValue(this).checkBits(1, this);
|
||||||
|
outReadValue = inputs.get(2).addObserverToValue(this).checkBits(bits, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
wr = wrValue.getValue();
|
||||||
|
oe = oeValue.getBool();
|
||||||
|
outRead = outReadValue.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
if (oe) {
|
||||||
|
outWriteValue.setValue(wr);
|
||||||
|
rdValue.setValue(wr);
|
||||||
|
} else {
|
||||||
|
outWriteValue.setToHighZ();
|
||||||
|
rdValue.setValue(outRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableValues getOutputs() {
|
||||||
|
return new ObservableValues(rdValue, outWriteValue);
|
||||||
|
}
|
||||||
|
}
|
@ -143,7 +143,8 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
.add(Keyboard.DESCRIPTION)
|
.add(Keyboard.DESCRIPTION)
|
||||||
.add(Terminal.DESCRIPTION)
|
.add(Terminal.DESCRIPTION)
|
||||||
.add(VGA.DESCRIPTION)
|
.add(VGA.DESCRIPTION)
|
||||||
.add(MIDI.DESCRIPTION)))
|
.add(MIDI.DESCRIPTION)
|
||||||
|
.add(PinControl.DESCRIPTION)))
|
||||||
.add(new LibraryNode(Lang.get("lib_wires"))
|
.add(new LibraryNode(Lang.get("lib_wires"))
|
||||||
.add(Ground.DESCRIPTION)
|
.add(Ground.DESCRIPTION)
|
||||||
.add(VDD.DESCRIPTION)
|
.add(VDD.DESCRIPTION)
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
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.PinDescriptions;
|
||||||
|
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 shape for the pin control logic
|
||||||
|
*/
|
||||||
|
public class PinControlShape implements Shape {
|
||||||
|
private final PinDescriptions in;
|
||||||
|
private final PinDescriptions out;
|
||||||
|
private Pins pins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param attr the elements attributes
|
||||||
|
* @param in the inputs
|
||||||
|
* @param out the outputs
|
||||||
|
*/
|
||||||
|
public PinControlShape(ElementAttributes attr, PinDescriptions in, PinDescriptions out) {
|
||||||
|
this.in = in;
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pins getPins() {
|
||||||
|
if (pins == null)
|
||||||
|
pins = new Pins()
|
||||||
|
.add(new Pin(new Vector(0, 0), in.get(0)))
|
||||||
|
.add(new Pin(new Vector(SIZE, -SIZE), in.get(1)))
|
||||||
|
.add(new Pin(new Vector(SIZE * 2, SIZE), out.get(0)))
|
||||||
|
.add(new Pin(new Vector(SIZE * 3, 0), out.get(1)));
|
||||||
|
return pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic, Style highLight) {
|
||||||
|
graphic.drawLine(new Vector(0, 0), new Vector(SIZE2, 0), Style.NORMAL);
|
||||||
|
graphic.drawLine(new Vector(SIZE + SIZE2, 0), new Vector(SIZE * 3, 0), Style.NORMAL);
|
||||||
|
graphic.drawLine(new Vector(SIZE * 2, 0), new Vector(SIZE * 2, SIZE), Style.NORMAL);
|
||||||
|
graphic.drawPolygon(new Polygon()
|
||||||
|
.add(SIZE2, SIZE2)
|
||||||
|
.add(SIZE2, -SIZE2)
|
||||||
|
.add(SIZE + SIZE2, 0), Style.NORMAL);
|
||||||
|
graphic.drawLine(new Vector(SIZE, -SIZE), new Vector(SIZE, -6), Style.NORMAL);
|
||||||
|
}
|
||||||
|
}
|
@ -163,6 +163,7 @@ public final class ShapeFactory {
|
|||||||
map.put(DiodeBackward.DESCRIPTION.getName(), DiodeBackwardShape::new);
|
map.put(DiodeBackward.DESCRIPTION.getName(), DiodeBackwardShape::new);
|
||||||
map.put(PullUp.DESCRIPTION.getName(), PullUpShape::new);
|
map.put(PullUp.DESCRIPTION.getName(), PullUpShape::new);
|
||||||
map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new);
|
map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new);
|
||||||
|
map.put(PinControl.DESCRIPTION.getName(), PinControlShape::new);
|
||||||
|
|
||||||
// disables string formatting for external components, see #272
|
// disables string formatting for external components, see #272
|
||||||
map.put(External.DESCRIPTION.getName(),
|
map.put(External.DESCRIPTION.getName(),
|
||||||
|
@ -44,6 +44,7 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Printable {
|
public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Printable {
|
||||||
private final String elementName;
|
private final String elementName;
|
||||||
|
private final int depth;
|
||||||
private final ArrayList<HDLPort> outputs;
|
private final ArrayList<HDLPort> outputs;
|
||||||
private final ArrayList<HDLPort> inputs;
|
private final ArrayList<HDLPort> inputs;
|
||||||
private final ArrayList<HDLNet> listOfNets;
|
private final ArrayList<HDLNet> listOfNets;
|
||||||
@ -61,12 +62,13 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
* @param circuit the circuit
|
* @param circuit the circuit
|
||||||
* @param elementName the name of the circuit
|
* @param elementName the name of the circuit
|
||||||
* @param c the context to create the circuits
|
* @param c the context to create the circuits
|
||||||
|
* @param depth the depth of this circuit in the circuits hierarchy
|
||||||
* @throws PinException PinException
|
* @throws PinException PinException
|
||||||
* @throws HDLException HDLException
|
* @throws HDLException HDLException
|
||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
HDLCircuit(Circuit circuit, String elementName, HDLModel c) throws PinException, HDLException, NodeException {
|
HDLCircuit(Circuit circuit, String elementName, HDLModel c, int depth) throws PinException, HDLException, NodeException {
|
||||||
this(circuit, elementName, c, null);
|
this(circuit, elementName, c, depth, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,13 +77,15 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
* @param circuit the circuit
|
* @param circuit the circuit
|
||||||
* @param elementName the name of the circuit
|
* @param elementName the name of the circuit
|
||||||
* @param c the context to create the circuits
|
* @param c the context to create the circuits
|
||||||
|
* @param depth the depth of this circuit in the circuits hierarchy
|
||||||
* @param clockIntegrator the clock integrator
|
* @param clockIntegrator the clock integrator
|
||||||
* @throws PinException PinException
|
* @throws PinException PinException
|
||||||
* @throws HDLException HDLException
|
* @throws HDLException HDLException
|
||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
public HDLCircuit(Circuit circuit, String elementName, HDLModel c, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException {
|
public HDLCircuit(Circuit circuit, String elementName, HDLModel c, int depth, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException {
|
||||||
this.elementName = elementName;
|
this.elementName = elementName;
|
||||||
|
this.depth = depth;
|
||||||
|
|
||||||
if (elementName.toLowerCase().endsWith(".dig"))
|
if (elementName.toLowerCase().endsWith(".dig"))
|
||||||
hdlEntityName = elementName.substring(0, elementName.length() - 4);
|
hdlEntityName = elementName.substring(0, elementName.length() - 4);
|
||||||
@ -154,12 +158,18 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
nodes.addAll(newNodes);
|
nodes.addAll(newNodes);
|
||||||
|
|
||||||
for (HDLPort i : inputs)
|
for (HDLPort i : inputs)
|
||||||
if (i.getNet() != null)
|
if (i.getNet() != null) {
|
||||||
i.getNet().setIsInput(i.getName());
|
i.getNet().setIsInput(i.getName());
|
||||||
|
if (i.getNet().isInOutNet())
|
||||||
|
i.setInOut();
|
||||||
|
}
|
||||||
|
|
||||||
for (HDLPort o : outputs)
|
for (HDLPort o : outputs) {
|
||||||
if (o.getNet().needsVariable())
|
if (o.getNet().needsVariable())
|
||||||
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
||||||
|
if (o.getNet().isInOutNet())
|
||||||
|
o.setInOut();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,6 +568,13 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the depth of this circuit in the circuits hierarchy
|
||||||
|
*/
|
||||||
|
public int getDepth() {
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The net naming algorithm
|
* The net naming algorithm
|
||||||
*/
|
*/
|
||||||
|
@ -10,11 +10,7 @@ import de.neemann.digital.core.ObservableValues;
|
|||||||
import de.neemann.digital.core.basic.*;
|
import de.neemann.digital.core.basic.*;
|
||||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.core.element.PinDescription;
|
import de.neemann.digital.core.io.*;
|
||||||
import de.neemann.digital.core.io.Const;
|
|
||||||
import de.neemann.digital.core.io.DipSwitch;
|
|
||||||
import de.neemann.digital.core.io.Ground;
|
|
||||||
import de.neemann.digital.core.io.VDD;
|
|
||||||
import de.neemann.digital.draw.elements.Circuit;
|
import de.neemann.digital.draw.elements.Circuit;
|
||||||
import de.neemann.digital.draw.elements.Pin;
|
import de.neemann.digital.draw.elements.Pin;
|
||||||
import de.neemann.digital.draw.elements.PinException;
|
import de.neemann.digital.draw.elements.PinException;
|
||||||
@ -77,7 +73,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
if (c == null) {
|
if (c == null) {
|
||||||
String elementName = v.getElementName();
|
String elementName = v.getElementName();
|
||||||
elementName = cleanName(elementName.substring(0, elementName.length() - 4) + "_gen" + cache.getNum() + ".dig");
|
elementName = cleanName(elementName.substring(0, elementName.length() - 4) + "_gen" + cache.getNum() + ".dig");
|
||||||
c = new HDLCircuit(holder.getCircuit(), elementName, this);
|
c = new HDLCircuit(holder.getCircuit(), elementName, this, parent.getDepth() + 1);
|
||||||
cache.addHDLCircuit(c, holder.getArgs());
|
cache.addHDLCircuit(c, holder.getArgs());
|
||||||
circuitMap.put(holder.getCircuit(), c);
|
circuitMap.put(holder.getCircuit(), c);
|
||||||
}
|
}
|
||||||
@ -90,7 +86,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
HDLCircuit c = circuitMap.get(circuit);
|
HDLCircuit c = circuitMap.get(circuit);
|
||||||
final String elementName = cleanName(v.getElementName());
|
final String elementName = cleanName(v.getElementName());
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
c = new HDLCircuit(circuit, elementName, this);
|
c = new HDLCircuit(circuit, elementName, this, parent.getDepth() + 1);
|
||||||
circuitMap.put(circuit, c);
|
circuitMap.put(circuit, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +147,6 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
td.createElement(v.getElementAttributes()).getOutputs())),
|
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||||
v, parent).createExpressions();
|
v, parent).createExpressions();
|
||||||
|
|
||||||
|
|
||||||
} catch (ElementNotFoundException | PinException | NodeException e) {
|
} catch (ElementNotFoundException | PinException | NodeException e) {
|
||||||
throw new HDLException("error creating node", e);
|
throw new HDLException("error creating node", e);
|
||||||
}
|
}
|
||||||
@ -180,10 +175,22 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
private <N extends HDLNode> N addInputsOutputs(N node, VisualElement v, HDLCircuit c) throws HDLException {
|
private <N extends HDLNode> N addInputsOutputs(N node, VisualElement v, HDLCircuit c) throws HDLException {
|
||||||
for (Pin p : v.getPins()) {
|
for (Pin p : v.getPins()) {
|
||||||
HDLNet net = c.getNetOfPin(p);
|
HDLNet net = c.getNetOfPin(p);
|
||||||
if (p.getDirection().equals(PinDescription.Direction.input))
|
switch (p.getDirection()) {
|
||||||
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
case input:
|
||||||
else
|
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
||||||
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
break;
|
||||||
|
case output:
|
||||||
|
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
||||||
|
break;
|
||||||
|
case both:
|
||||||
|
if (v.equalsDescription(PinControl.DESCRIPTION)) {
|
||||||
|
if (c.getDepth() != 0)
|
||||||
|
throw new HDLException("PinControl component is allowed only in the top level circuit");
|
||||||
|
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.INOUT, node.getBits(p.getName())));
|
||||||
|
} else
|
||||||
|
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -205,7 +212,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
public HDLModel create(Circuit circuit, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException {
|
public HDLModel create(Circuit circuit, HDLClockIntegrator clockIntegrator) throws PinException, HDLException, NodeException {
|
||||||
main = new HDLCircuit(circuit, "main", this, clockIntegrator);
|
main = new HDLCircuit(circuit, "main", this, 0, clockIntegrator);
|
||||||
circuitMap.put(circuit, main);
|
circuitMap.put(circuit, main);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,9 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class HDLNet implements Printable, HasName {
|
public class HDLNet implements Printable, HasName {
|
||||||
private final boolean userNamed;
|
private final boolean userNamed;
|
||||||
|
private final ArrayList<HDLPort> inputs;
|
||||||
|
private final ArrayList<HDLPort> inOutputs;
|
||||||
private String name;
|
private String name;
|
||||||
private ArrayList<HDLPort> inputs;
|
|
||||||
private HDLPort output;
|
private HDLPort output;
|
||||||
private boolean needsVariable = true;
|
private boolean needsVariable = true;
|
||||||
private boolean isInput;
|
private boolean isInput;
|
||||||
@ -32,6 +33,7 @@ public class HDLNet implements Printable, HasName {
|
|||||||
public HDLNet(String name) {
|
public HDLNet(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
inputs = new ArrayList<>();
|
inputs = new ArrayList<>();
|
||||||
|
inOutputs = new ArrayList<>();
|
||||||
userNamed = name != null;
|
userNamed = name != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,16 +51,23 @@ public class HDLNet implements Printable, HasName {
|
|||||||
* @throws HDLException HDLException
|
* @throws HDLException HDLException
|
||||||
*/
|
*/
|
||||||
public void addPort(HDLPort hdlPort) throws HDLException {
|
public void addPort(HDLPort hdlPort) throws HDLException {
|
||||||
if (hdlPort.getDirection().equals(HDLPort.Direction.OUT)) {
|
switch (hdlPort.getDirection()) {
|
||||||
if (output != null) {
|
case OUT:
|
||||||
String netName = name;
|
if (output != null) {
|
||||||
if (netName == null)
|
String netName = name;
|
||||||
netName = Lang.get("err_unnamedNet");
|
if (netName == null)
|
||||||
throw new HDLException(Lang.get("err_hdlMultipleOutputsConnectedToNet_N_N_N", netName, output, hdlPort));
|
netName = Lang.get("err_unnamedNet");
|
||||||
}
|
throw new HDLException(Lang.get("err_hdlMultipleOutputsConnectedToNet_N_N_N", netName, output, hdlPort));
|
||||||
output = hdlPort;
|
}
|
||||||
} else
|
output = hdlPort;
|
||||||
inputs.add(hdlPort);
|
break;
|
||||||
|
case IN:
|
||||||
|
inputs.add(hdlPort);
|
||||||
|
break;
|
||||||
|
case INOUT:
|
||||||
|
inOutputs.add(hdlPort);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,11 +90,25 @@ public class HDLNet implements Printable, HasName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fixBits() throws HDLException {
|
void fixBits() throws HDLException {
|
||||||
if (output == null)
|
int bits = 0;
|
||||||
throw new HDLException("no output connected to net");
|
if (output == null) {
|
||||||
final int bits = output.getBits();
|
if (inOutputs.isEmpty())
|
||||||
if (bits == 0)
|
throw new HDLException("no output connected to net");
|
||||||
throw new HDLException("no bit number set for output " + output.getName());
|
else {
|
||||||
|
for (HDLPort p : inOutputs) {
|
||||||
|
if (p.getBits() > 0) {
|
||||||
|
bits = p.getBits();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bits == 0)
|
||||||
|
throw new HDLException("no bit number set for inOutputs " + inOutputs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bits = output.getBits();
|
||||||
|
if (bits == 0)
|
||||||
|
throw new HDLException("no bit number set for output " + output.getName());
|
||||||
|
}
|
||||||
|
|
||||||
for (HDLPort i : inputs)
|
for (HDLPort i : inputs)
|
||||||
i.setBits(bits);
|
i.setBits(bits);
|
||||||
@ -96,6 +119,8 @@ public class HDLNet implements Printable, HasName {
|
|||||||
* @return the constant if this net is a constant, null otherwise
|
* @return the constant if this net is a constant, null otherwise
|
||||||
*/
|
*/
|
||||||
public ExprConstant isConstant() {
|
public ExprConstant isConstant() {
|
||||||
|
if (output == null)
|
||||||
|
return null;
|
||||||
return ExprConstant.isConstant(output.getParent());
|
return ExprConstant.isConstant(output.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,9 +185,18 @@ public class HDLNet implements Printable, HasName {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of bits on this net
|
* @return the number of bits on this net
|
||||||
|
* @throws HDLException HDLException
|
||||||
*/
|
*/
|
||||||
public int getBits() {
|
public int getBits() throws HDLException {
|
||||||
return output.getBits();
|
if (output != null)
|
||||||
|
return output.getBits();
|
||||||
|
|
||||||
|
for (HDLPort p : inOutputs) {
|
||||||
|
if (p.getBits() > 0) {
|
||||||
|
return p.getBits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new HDLException("no bit number set for inOutputs " + inOutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,4 +224,11 @@ public class HDLNet implements Printable, HasName {
|
|||||||
name = renaming.checkName(name);
|
name = renaming.checkName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is a inOut net
|
||||||
|
*/
|
||||||
|
public boolean isInOutNet() {
|
||||||
|
return !inOutputs.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ public abstract class HDLNode {
|
|||||||
private final HDLModel.BitProvider bitProvider;
|
private final HDLModel.BitProvider bitProvider;
|
||||||
private final ArrayList<HDLPort> inputs;
|
private final ArrayList<HDLPort> inputs;
|
||||||
private final ArrayList<HDLPort> outputs;
|
private final ArrayList<HDLPort> outputs;
|
||||||
|
private final ArrayList<HDLPort> inOutputs;
|
||||||
private String hdlEntityName;
|
private String hdlEntityName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,6 +38,7 @@ public abstract class HDLNode {
|
|||||||
this.bitProvider = bitProvider;
|
this.bitProvider = bitProvider;
|
||||||
inputs = new ArrayList<>();
|
inputs = new ArrayList<>();
|
||||||
outputs = new ArrayList<>();
|
outputs = new ArrayList<>();
|
||||||
|
inOutputs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,10 +48,17 @@ public abstract class HDLNode {
|
|||||||
* @return this for chained calls
|
* @return this for chained calls
|
||||||
*/
|
*/
|
||||||
public HDLNode addPort(HDLPort port) {
|
public HDLNode addPort(HDLPort port) {
|
||||||
if (port.getDirection().equals(HDLPort.Direction.OUT))
|
switch (port.getDirection()) {
|
||||||
outputs.add(port);
|
case IN:
|
||||||
else
|
inputs.add(port);
|
||||||
inputs.add(port);
|
break;
|
||||||
|
case OUT:
|
||||||
|
outputs.add(port);
|
||||||
|
break;
|
||||||
|
case INOUT:
|
||||||
|
inOutputs.add(port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
port.setParent(this);
|
port.setParent(this);
|
||||||
|
|
||||||
@ -96,6 +105,13 @@ public abstract class HDLNode {
|
|||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the list of inOutputs
|
||||||
|
*/
|
||||||
|
public ArrayList<HDLPort> getInOutputs() {
|
||||||
|
return inOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
int getBits(String name) {
|
int getBits(String name) {
|
||||||
return bitProvider.getBits(name);
|
return bitProvider.getBits(name);
|
||||||
}
|
}
|
||||||
@ -111,6 +127,10 @@ public abstract class HDLNode {
|
|||||||
printWithLocal(out, inputs);
|
printWithLocal(out, inputs);
|
||||||
out.print("out");
|
out.print("out");
|
||||||
printWithLocal(out, outputs);
|
printWithLocal(out, outputs);
|
||||||
|
if (!inOutputs.isEmpty()) {
|
||||||
|
out.print("inOut");
|
||||||
|
printWithLocal(out, inOutputs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printWithLocal(CodePrinter out, ArrayList<HDLPort> ports) throws IOException {
|
private void printWithLocal(CodePrinter out, ArrayList<HDLPort> ports) throws IOException {
|
||||||
@ -177,6 +197,8 @@ public abstract class HDLNode {
|
|||||||
p.rename(renaming);
|
p.rename(renaming);
|
||||||
for (HDLPort p : inputs)
|
for (HDLPort p : inputs)
|
||||||
p.rename(renaming);
|
p.rename(renaming);
|
||||||
|
for (HDLPort p : inOutputs)
|
||||||
|
p.rename(renaming);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,11 +30,15 @@ public class HDLPort implements Printable, HasName {
|
|||||||
* Caution: a circuits input components port has type OUT because it defines a value,
|
* Caution: a circuits input components port has type OUT because it defines a value,
|
||||||
* seen from inside the node.
|
* seen from inside the node.
|
||||||
*/
|
*/
|
||||||
OUT
|
OUT,
|
||||||
|
/**
|
||||||
|
* Bidirectional port
|
||||||
|
*/
|
||||||
|
INOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private final Direction direction;
|
private Direction direction;
|
||||||
private int bits;
|
private int bits;
|
||||||
private String description;
|
private String description;
|
||||||
private boolean isClock;
|
private boolean isClock;
|
||||||
@ -213,4 +217,11 @@ public class HDLPort implements Printable, HasName {
|
|||||||
name = renaming.checkName(name);
|
name = renaming.checkName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets this port to a inOut mode port
|
||||||
|
*/
|
||||||
|
public void setInOut() {
|
||||||
|
direction = Direction.INOUT;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -56,12 +56,17 @@ public class VerilogCreator {
|
|||||||
/**
|
/**
|
||||||
* Returns the verilog type for a signal
|
* Returns the verilog type for a signal
|
||||||
*
|
*
|
||||||
* @param dir the signal type (input or output)
|
* @param def the signal type (input or output) used if dir is not "inout"
|
||||||
|
* @param dir used to check if direction is "inout"
|
||||||
* @param bits the number of bits
|
* @param bits the number of bits
|
||||||
* @return the verilog signal type
|
* @return the verilog signal type
|
||||||
*/
|
*/
|
||||||
public static String getType(HDLPort.Direction dir, int bits) {
|
public static String getType(HDLPort.Direction def, HDLPort.Direction dir, int bits) {
|
||||||
String result = (dir == HDLPort.Direction.IN) ? "input" : "output";
|
String result;
|
||||||
|
if (dir == HDLPort.Direction.INOUT)
|
||||||
|
result = "inout";
|
||||||
|
else
|
||||||
|
result = (def == HDLPort.Direction.IN) ? "input" : "output";
|
||||||
|
|
||||||
if (bits > 1) {
|
if (bits > 1) {
|
||||||
result += " [" + (bits - 1) + ":0]";
|
result += " [" + (bits - 1) + ":0]";
|
||||||
@ -181,12 +186,12 @@ public class VerilogCreator {
|
|||||||
|
|
||||||
for (HDLPort i : circuit.getInputs()) {
|
for (HDLPort i : circuit.getInputs()) {
|
||||||
sep.check();
|
sep.check();
|
||||||
out.print(getType(HDLPort.Direction.IN, i.getBits())).print(" ").print(i.getName());
|
out.print(getType(HDLPort.Direction.IN, i.getDirection(), i.getBits())).print(" ").print(i.getName());
|
||||||
if (i.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" // ", i.getDescription()));
|
if (i.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" // ", i.getDescription()));
|
||||||
}
|
}
|
||||||
for (HDLPort o : circuit.getOutputs()) {
|
for (HDLPort o : circuit.getOutputs()) {
|
||||||
sep.check();
|
sep.check();
|
||||||
out.print(getType(HDLPort.Direction.OUT, o.getBits())).print(" ").print(o.getName());
|
out.print(getType(HDLPort.Direction.OUT, o.getDirection(), o.getBits())).print(" ").print(o.getName());
|
||||||
if (o.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" // ", o.getDescription()));
|
if (o.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" // ", o.getDescription()));
|
||||||
}
|
}
|
||||||
sep.close();
|
sep.close();
|
||||||
@ -260,6 +265,12 @@ public class VerilogCreator {
|
|||||||
sep.check();
|
sep.check();
|
||||||
out.print(".").print(o.getName()).print("( ").print(o.getNet().getName()).print(" )");
|
out.print(".").print(o.getName()).print("( ").print(o.getNet().getName()).print(" )");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (HDLPort o : node.getInOutputs())
|
||||||
|
if (o.getNet() != null) {
|
||||||
|
sep.check();
|
||||||
|
out.print(".").print(o.getName()).print("( ").print(o.getNet().getName()).print(" )");
|
||||||
|
}
|
||||||
out.dec();
|
out.dec();
|
||||||
out.println().println(");");
|
out.println().println(");");
|
||||||
}
|
}
|
||||||
|
@ -178,18 +178,24 @@ public class VHDLCreator {
|
|||||||
|
|
||||||
for (HDLPort i : circuit.getInputs()) {
|
for (HDLPort i : circuit.getInputs()) {
|
||||||
sep.check();
|
sep.check();
|
||||||
out.print(i.getName()).print(": in ").print(getType(i.getBits()));
|
out.print(i.getName()).print(": ").print(getDir(i.getDirection(), "in")).print(" ").print(getType(i.getBits()));
|
||||||
if (i.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" -- ", i.getDescription()));
|
if (i.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" -- ", i.getDescription()));
|
||||||
}
|
}
|
||||||
for (HDLPort o : circuit.getOutputs()) {
|
for (HDLPort o : circuit.getOutputs()) {
|
||||||
sep.check();
|
sep.check();
|
||||||
out.print(o.getName()).print(": out ").print(getType(o.getBits()));
|
out.print(o.getName()).print(": ").print(getDir(o.getDirection(), "out")).print(" ").print(getType(o.getBits()));
|
||||||
if (o.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" -- ", o.getDescription()));
|
if (o.hasDescription()) sep.setLineFinalizer(ou -> ou.printComment(" -- ", o.getDescription()));
|
||||||
}
|
}
|
||||||
sep.close();
|
sep.close();
|
||||||
out.println(");").dec();
|
out.println(");").dec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getDir(HDLPort.Direction direction, String def) {
|
||||||
|
if (direction == HDLPort.Direction.INOUT)
|
||||||
|
return "inout";
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
private void printManyToOne(HDLNodeSplitterManyToOne node) throws IOException, HDLException {
|
private void printManyToOne(HDLNodeSplitterManyToOne node) throws IOException, HDLException {
|
||||||
String target = node.getTargetSignal();
|
String target = node.getTargetSignal();
|
||||||
|
|
||||||
@ -250,6 +256,11 @@ public class VHDLCreator {
|
|||||||
sep.check();
|
sep.check();
|
||||||
out.print(o.getName()).print(" => ").print(o.getNet().getName());
|
out.print(o.getName()).print(" => ").print(o.getNet().getName());
|
||||||
}
|
}
|
||||||
|
for (HDLPort o : node.getInOutputs())
|
||||||
|
if (o.getNet() != null) {
|
||||||
|
sep.check();
|
||||||
|
out.print(o.getName()).print(" => ").print(o.getNet().getName());
|
||||||
|
}
|
||||||
out.println(");").dec().dec();
|
out.println(");").dec().dec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,25 +338,47 @@
|
|||||||
<string name="elem_Driver_pin_sel">Eingang zum Steuern des Treibers.
|
<string name="elem_Driver_pin_sel">Eingang zum Steuern des Treibers.
|
||||||
Ist dieser Eingang auf 1 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 0, ist der Ausgang hochohmig.</string>
|
Ist dieser Eingang auf 1 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 0, ist der Ausgang hochohmig.</string>
|
||||||
<string name="elem_DriverInvSel">Treiber, invertierte Auswahl</string>
|
<string name="elem_DriverInvSel">Treiber, invertierte Auswahl</string>
|
||||||
<string name="elem_DriverInvSel_tt">Ein Treiber kann dazu verwendet werden, ein Datenwort nur unter speziellen Voraussetzungen auf eine andere Leitung weiterzureichen.
|
<string name="elem_DriverInvSel_tt">Ein Treiber kann dazu verwendet werden, ein Datenwort nur unter speziellen
|
||||||
|
Voraussetzungen auf eine andere Leitung weiterzureichen.
|
||||||
Gesteuert wird der Treiber durch den sel Eingang.
|
Gesteuert wird der Treiber durch den sel Eingang.
|
||||||
Ist der sel Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht.
|
Ist der sel Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht.
|
||||||
Ist der Eingang 1, ist der Ausgang hochohmig.
|
Ist der Eingang 1, ist der Ausgang hochohmig.
|
||||||
</string>
|
</string>
|
||||||
<string name="elem_DriverInvSel_pin_in">Das Eingangssignal des Treibers.</string>
|
<string name="elem_DriverInvSel_pin_in">Das Eingangssignal des Treibers.</string>
|
||||||
<string name="elem_DriverInvSel_pin_sel">Eingang zum Steuern des Treibers.
|
<string name="elem_DriverInvSel_pin_sel">Eingang zum Steuern des Treibers.
|
||||||
Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1, ist der Ausgang hochohmig.</string>
|
Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1,
|
||||||
<string name="elem_DriverInvSel_pin_out">Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0 gesetzt ist.</string>
|
ist der Ausgang hochohmig.
|
||||||
|
</string>
|
||||||
|
<string name="elem_DriverInvSel_pin_out">Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0
|
||||||
|
gesetzt ist.
|
||||||
|
</string>
|
||||||
|
|
||||||
|
<string name="elem_PinControl">Pinsteuerung</string>
|
||||||
|
<string name="elem_PinControl_tt">Steuerlogik für einen bidirektionalen Pin.
|
||||||
|
Diese ist nur im Rahmen der VHDL- oder Verilog-Generierung erforderlich, um einen bidirektionalen HDL-Port zu
|
||||||
|
erstellen!
|
||||||
|
Wenn Sie keinen bidirektionalen IO-Port auf einem FPGA verwenden wollen, verwenden Sie diese Komponente nicht!
|
||||||
|
Die Pinsteuerung kann nicht in einer eingebetteten Schaltung verwendet werden! Sie ist nur auf der obersten
|
||||||
|
Schaltungsebene erlaubt!
|
||||||
|
</string>
|
||||||
|
<string name="elem_PinControl_pin_wr">Die auszugebenden Daten</string>
|
||||||
|
<string name="elem_PinControl_pin_oe">Aktiviert die Ausgabe</string>
|
||||||
|
<string name="elem_PinControl_pin_rd">Die zu lesenden Daten.</string>
|
||||||
|
<string name="elem_PinControl_pin_pin">Der Anschluss für den eigentlichen Pin. Hier sollte nur noch ein einzelner
|
||||||
|
Ausgang angeschlossen werden.
|
||||||
|
</string>
|
||||||
|
|
||||||
<!-- Plexers -->
|
<!-- Plexers -->
|
||||||
|
|
||||||
<string name="elem_Multiplexer">Multiplexer</string>
|
<string name="elem_Multiplexer">Multiplexer</string>
|
||||||
<string name="elem_Multiplexer_tt">Ein Baustein, welcher den Wert eines der Eingänge am Ausgang ausgibt.
|
<string name="elem_Multiplexer_tt">Ein Baustein, welcher den Wert eines der Eingänge am Ausgang ausgibt.
|
||||||
Über den sel-Eingang wird ausgewählt, welcher der Eingänge ausgegeben werden soll.</string>
|
Über den sel-Eingang wird ausgewählt, welcher der Eingänge ausgegeben werden soll.
|
||||||
|
</string>
|
||||||
<string name="elem_Multiplexer_input">Der {0}. Dateneingang des Multiplexers.</string>
|
<string name="elem_Multiplexer_input">Der {0}. Dateneingang des Multiplexers.</string>
|
||||||
<string name="elem_Multiplexer_output">Ausgeben wird der Wert, der am gewählten Dateneingang anliegt.</string>
|
<string name="elem_Multiplexer_output">Ausgeben wird der Wert, der am gewählten Dateneingang anliegt.</string>
|
||||||
<string name="elem_Multiplexer_pin_sel">Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang ausgegeben werden soll.</string>
|
<string name="elem_Multiplexer_pin_sel">Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang
|
||||||
|
ausgegeben werden soll.
|
||||||
|
</string>
|
||||||
<string name="elem_Demultiplexer">Demultiplexer</string>
|
<string name="elem_Demultiplexer">Demultiplexer</string>
|
||||||
<string name="elem_Demultiplexer_tt">Ein Baustein, welcher einen Eingangswert auf verschiedene Ausgänge ausgeben kann.
|
<string name="elem_Demultiplexer_tt">Ein Baustein, welcher einen Eingangswert auf verschiedene Ausgänge ausgeben kann.
|
||||||
Gibt das Eingangssignal auf einem wählbaren Ausgang aus. Die anderen Ausgänge werden auf den Vorgabewert gesetzt.</string>
|
Gibt das Eingangssignal auf einem wählbaren Ausgang aus. Die anderen Ausgänge werden auf den Vorgabewert gesetzt.</string>
|
||||||
|
@ -363,11 +363,26 @@
|
|||||||
If the sel input is 1, this output is in high z state.
|
If the sel input is 1, this output is in high z state.
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
|
<string name="elem_PinControl">Pin Control</string>
|
||||||
|
<string name="elem_PinControl_tt">Control logic for a bi-directional pin.
|
||||||
|
This component is necessary only in the context of VHDL or Verilog generation, in order to create a
|
||||||
|
bi-directional HDL port!
|
||||||
|
If you don't want to use a bi-directional IO-port on an FPGA, don't use this component!
|
||||||
|
The PinControl component cannot be used in an embedded circuit! It is only allowed at the top level circuit!
|
||||||
|
</string>
|
||||||
|
<string name="elem_PinControl_pin_wr">The data to be output.</string>
|
||||||
|
<string name="elem_PinControl_pin_oe">Activates the output.</string>
|
||||||
|
<string name="elem_PinControl_pin_rd">The data to be read.</string>
|
||||||
|
<string name="elem_PinControl_pin_pin">The connector for the actual pin. Only a single output should be connected
|
||||||
|
here.
|
||||||
|
</string>
|
||||||
|
|
||||||
<!-- Plexers -->
|
<!-- Plexers -->
|
||||||
|
|
||||||
<string name="elem_Multiplexer">Multiplexer</string>
|
<string name="elem_Multiplexer">Multiplexer</string>
|
||||||
<string name="elem_Multiplexer_tt">A component which uses the value of the sel pin to decide which input value is set to the output.</string>
|
<string name="elem_Multiplexer_tt">A component which uses the value of the sel pin to decide which input value is
|
||||||
|
set to the output.
|
||||||
|
</string>
|
||||||
<string name="elem_Multiplexer_input">The {0}. data input of the multiplexer.</string>
|
<string name="elem_Multiplexer_input">The {0}. data input of the multiplexer.</string>
|
||||||
<string name="elem_Multiplexer_output">The value of the selected input.</string>
|
<string name="elem_Multiplexer_output">The value of the selected input.</string>
|
||||||
<string name="elem_Multiplexer_pin_sel">This input is used to select the data input which is output.</string>
|
<string name="elem_Multiplexer_pin_sel">This input is used to select the data input which is output.</string>
|
||||||
|
26
src/main/resources/verilog/DIG_PinControl.v
Normal file
26
src/main/resources/verilog/DIG_PinControl.v
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?
|
||||||
|
if (elem.Bits > 1) {
|
||||||
|
generics[0] := "Bits";
|
||||||
|
export bitRange := "[(Bits-1):0] ";
|
||||||
|
export zval := "{Bits{1'bz}}";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
moduleName = moduleName+"_BUS";
|
||||||
|
export bitRange := "";
|
||||||
|
export zval := "1'bz";
|
||||||
|
}
|
||||||
|
?>module <?= moduleName ?><?
|
||||||
|
if (elem.Bits > 1) { ?>
|
||||||
|
#(
|
||||||
|
parameter Bits = 2
|
||||||
|
)
|
||||||
|
<? } ?>(
|
||||||
|
inout <?= bitRange ?>pin,
|
||||||
|
input oe,
|
||||||
|
input <?= bitRange ?>wr,
|
||||||
|
output <?= bitRange ?>rd
|
||||||
|
);
|
||||||
|
|
||||||
|
assign pin = oe ? wr : <?= zval ?>;
|
||||||
|
assign rd = oe ? wr : pin ;
|
||||||
|
endmodule
|
64
src/main/resources/vhdl/DIG_PinControl.tem
Normal file
64
src/main/resources/vhdl/DIG_PinControl.tem
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
LIBRARY ieee;
|
||||||
|
USE ieee.std_logic_1164.all;
|
||||||
|
<?
|
||||||
|
if (elem.Bits=1) {
|
||||||
|
export entityName:="PinControl"; ?>
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
USE ieee.std_logic_1164.ALL;
|
||||||
|
|
||||||
|
ENTITY PinControl IS
|
||||||
|
PORT(
|
||||||
|
pin : INOUT STD_LOGIC;
|
||||||
|
oe : IN STD_LOGIC;
|
||||||
|
wr : IN STD_LOGIC;
|
||||||
|
rd : OUT STD_LOGIC);
|
||||||
|
END PinControl;
|
||||||
|
|
||||||
|
ARCHITECTURE Behavioral OF PinControl IS
|
||||||
|
BEGIN
|
||||||
|
PROCESS (oe, pin, wr) -- Behavioral representation
|
||||||
|
BEGIN -- of tri-states.
|
||||||
|
IF( oe = '0') THEN
|
||||||
|
pin <= 'Z';
|
||||||
|
rd <= pin;
|
||||||
|
ELSE
|
||||||
|
pin <= wr;
|
||||||
|
rd <= wr;
|
||||||
|
END IF;
|
||||||
|
END PROCESS;
|
||||||
|
END Behavioral;
|
||||||
|
|
||||||
|
<? } else {
|
||||||
|
export entityName:="PinControl_BUS"; ?>
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
USE ieee.std_logic_1164.ALL;
|
||||||
|
|
||||||
|
ENTITY PinControl_BUS IS
|
||||||
|
GENERIC (
|
||||||
|
Bits: integer );<? vhdl.registerGeneric("Bits"); ?>
|
||||||
|
PORT(
|
||||||
|
pin : INOUT std_logic_vector((Bits-1) downto 0);
|
||||||
|
oe : IN STD_LOGIC;
|
||||||
|
wr : IN std_logic_vector((Bits-1) downto 0);
|
||||||
|
rd : OUT std_logic_vector((Bits-1) downto 0));
|
||||||
|
END PinControl_BUS;
|
||||||
|
|
||||||
|
ARCHITECTURE Behavioral OF PinControl_BUS IS
|
||||||
|
BEGIN
|
||||||
|
PROCESS (oe, pin, wr) -- Behavioral representation
|
||||||
|
BEGIN -- of tri-states.
|
||||||
|
IF( oe = '0') THEN
|
||||||
|
pin <= (others => 'Z');
|
||||||
|
rd <= pin;
|
||||||
|
ELSE
|
||||||
|
pin <= wr;
|
||||||
|
rd <= wr;
|
||||||
|
END IF;
|
||||||
|
END PROCESS;
|
||||||
|
END Behavioral;
|
||||||
|
|
||||||
|
<?
|
||||||
|
}
|
||||||
|
?>
|
@ -21,7 +21,7 @@ public class HDLModelTest extends TestCase {
|
|||||||
|
|
||||||
private HDLCircuit getCircuit(String filename, HDLClockIntegrator ci) throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
private HDLCircuit getCircuit(String filename, HDLClockIntegrator ci) throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
||||||
ToBreakRunner br = new ToBreakRunner(filename);
|
ToBreakRunner br = new ToBreakRunner(filename);
|
||||||
return new HDLCircuit(br.getCircuit(), "main", new HDLModel(br.getLibrary()), ci);
|
return new HDLCircuit(br.getCircuit(), "main", new HDLModel(br.getLibrary()), 0, ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSimple() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
public void testSimple() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
|
||||||
|
@ -26,7 +26,7 @@ public class DescriptionTest extends TestCase {
|
|||||||
br.getCircuit(),
|
br.getCircuit(),
|
||||||
"main"
|
"main"
|
||||||
, new HDLModel(br.getLibrary()),
|
, new HDLModel(br.getLibrary()),
|
||||||
null)
|
0, null)
|
||||||
.applyDefaultOptimizations();
|
.applyDefaultOptimizations();
|
||||||
CodePrinterStr out = new CodePrinterStr();
|
CodePrinterStr out = new CodePrinterStr();
|
||||||
new VerilogCreator(out, br.getLibrary()).printHDLCircuit(circuit, "naming");
|
new VerilogCreator(out, br.getLibrary()).printHDLCircuit(circuit, "naming");
|
||||||
|
@ -14,6 +14,7 @@ import de.neemann.digital.draw.library.ElementNotFoundException;
|
|||||||
import de.neemann.digital.gui.Settings;
|
import de.neemann.digital.gui.Settings;
|
||||||
import de.neemann.digital.hdl.model2.HDLException;
|
import de.neemann.digital.hdl.model2.HDLException;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
import de.neemann.digital.hdl.printer.CodePrinterStr;
|
||||||
import de.neemann.digital.integration.FileScanner;
|
import de.neemann.digital.integration.FileScanner;
|
||||||
import de.neemann.digital.integration.Resources;
|
import de.neemann.digital.integration.Resources;
|
||||||
import de.neemann.digital.integration.TestExamples;
|
import de.neemann.digital.integration.TestExamples;
|
||||||
@ -42,13 +43,13 @@ public class VerilogSimulatorTest extends TestCase {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
public void testDebug() throws Exception {
|
public void testDebug() throws Exception {
|
||||||
File file = new File(Resources.getRoot(), "dig/test/vhdl/lut.dig");
|
File file = new File(Resources.getRoot(), "/dig/test/vhdl/pinControl/simple.dig");
|
||||||
|
|
||||||
ToBreakRunner br = new ToBreakRunner(file);
|
ToBreakRunner br = new ToBreakRunner(file);
|
||||||
System.out.println(new VerilogGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
System.out.println(new VerilogGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
||||||
|
|
||||||
checkVerilogExport(file);
|
checkVerilogExport(file);
|
||||||
}*/
|
}/**/
|
||||||
|
|
||||||
public void testInSimulator() throws Exception {
|
public void testInSimulator() throws Exception {
|
||||||
File examples = new File(Resources.getRoot(), "/dig/test/vhdl");
|
File examples = new File(Resources.getRoot(), "/dig/test/vhdl");
|
||||||
@ -71,6 +72,21 @@ public class VerilogSimulatorTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testInSimulatorInOut() throws Exception {
|
||||||
|
File examples = new File(Resources.getRoot(), "/dig/test/pinControl");
|
||||||
|
try {
|
||||||
|
int tested = new FileScanner(f -> {
|
||||||
|
if (!f.getName().equals("uniTest.dig"))
|
||||||
|
checkVerilogExport(f);
|
||||||
|
}).noOutput().scan(examples);
|
||||||
|
assertEquals(2, tested);
|
||||||
|
assertEquals(1, testBenches);
|
||||||
|
} catch (FileScanner.SkipAllException e) {
|
||||||
|
// if iverilog is not installed its also ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testDistributedInSimulator() throws Exception {
|
public void testDistributedInSimulator() throws Exception {
|
||||||
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
||||||
try {
|
try {
|
||||||
@ -128,7 +144,7 @@ public class VerilogSimulatorTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
File srcFile = new File(dir, file.getName()
|
File srcFile = new File(dir, file.getName()
|
||||||
.replace('.', '_')
|
.replace('.', '_')
|
||||||
.replace('-', '_')+ ".v");
|
.replace('-', '_') + ".v");
|
||||||
CodePrinter out = new CodePrinter(srcFile);
|
CodePrinter out = new CodePrinter(srcFile);
|
||||||
try (VerilogGenerator gen = new VerilogGenerator(br.getLibrary(), out)) {
|
try (VerilogGenerator gen = new VerilogGenerator(br.getLibrary(), out)) {
|
||||||
gen.export(br.getCircuit());
|
gen.export(br.getCircuit());
|
||||||
|
@ -123,7 +123,7 @@ public class ClockTest extends TestCase {
|
|||||||
HDLCircuit c = new HDLCircuit(
|
HDLCircuit c = new HDLCircuit(
|
||||||
br.getCircuit(), "main",
|
br.getCircuit(), "main",
|
||||||
new HDLModel(br.getLibrary()),
|
new HDLModel(br.getLibrary()),
|
||||||
ci);
|
0, ci);
|
||||||
|
|
||||||
c.applyDefaultOptimizations();
|
c.applyDefaultOptimizations();
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class DescriptionTest extends TestCase {
|
|||||||
br.getCircuit(),
|
br.getCircuit(),
|
||||||
"main"
|
"main"
|
||||||
, new HDLModel(br.getLibrary()),
|
, new HDLModel(br.getLibrary()),
|
||||||
null)
|
0, null)
|
||||||
.applyDefaultOptimizations();
|
.applyDefaultOptimizations();
|
||||||
CodePrinterStr out = new CodePrinterStr();
|
CodePrinterStr out = new CodePrinterStr();
|
||||||
new VHDLCreator(out, br.getLibrary()).printHDLCircuit(circuit);
|
new VHDLCreator(out, br.getLibrary()).printHDLCircuit(circuit);
|
||||||
|
@ -34,7 +34,7 @@ public class VHDLSimulatorTest extends TestCase {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
public void testDebug() throws Exception {
|
public void testDebug() throws Exception {
|
||||||
File file = new File(Resources.getRoot(), "dig/test/vhdl/lut2.dig");
|
File file = new File(Resources.getRoot(), "/dig/test/pinControl/nesting.dig");
|
||||||
|
|
||||||
ToBreakRunner br = new ToBreakRunner(file);
|
ToBreakRunner br = new ToBreakRunner(file);
|
||||||
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
||||||
@ -63,6 +63,17 @@ public class VHDLSimulatorTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testInSimulatorInOut() throws Exception {
|
||||||
|
File examples = new File(Resources.getRoot(), "/dig/test/pinControl");
|
||||||
|
try {
|
||||||
|
int tested = new FileScanner(this::checkVHDLExport).noOutput().scan(examples);
|
||||||
|
assertEquals(2, tested);
|
||||||
|
assertEquals(2, testBenches);
|
||||||
|
} catch (FileScanner.SkipAllException e) {
|
||||||
|
// if ghdl is not installed its also ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testDistributedInSimulator() throws Exception {
|
public void testDistributedInSimulator() throws Exception {
|
||||||
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
||||||
try {
|
try {
|
||||||
|
@ -43,8 +43,8 @@ public class TestExamples extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testTestExamples() throws Exception {
|
public void testTestExamples() throws Exception {
|
||||||
File examples = new File(Resources.getRoot(), "/dig/test");
|
File examples = new File(Resources.getRoot(), "/dig/test");
|
||||||
assertEquals(184, new FileScanner(this::check).scan(examples));
|
assertEquals(186, new FileScanner(this::check).scan(examples));
|
||||||
assertEquals(172, testCasesInFiles);
|
assertEquals(174, testCasesInFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -614,6 +614,30 @@
|
|||||||
<elementAttributes/>
|
<elementAttributes/>
|
||||||
<pos x="600" y="920"/>
|
<pos x="600" y="920"/>
|
||||||
</visualElement>
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>PinControl</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>8</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="780" y="960"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Tunnel</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>rotation</string>
|
||||||
|
<rotation rotation="2"/>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>NetName</string>
|
||||||
|
<string>zz</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="740" y="1020"/>
|
||||||
|
</visualElement>
|
||||||
</visualElements>
|
</visualElements>
|
||||||
<wires>
|
<wires>
|
||||||
<wire>
|
<wire>
|
||||||
@ -668,6 +692,14 @@
|
|||||||
<p1 x="580" y="960"/>
|
<p1 x="580" y="960"/>
|
||||||
<p2 x="600" y="960"/>
|
<p2 x="600" y="960"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="760" y="960"/>
|
||||||
|
<p2 x="780" y="960"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="820" y="960"/>
|
||||||
|
<p2 x="840" y="960"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="240" y="260"/>
|
<p1 x="240" y="260"/>
|
||||||
<p2 x="260" y="260"/>
|
<p2 x="260" y="260"/>
|
||||||
@ -716,6 +748,10 @@
|
|||||||
<p1 x="1080" y="900"/>
|
<p1 x="1080" y="900"/>
|
||||||
<p2 x="1120" y="900"/>
|
<p2 x="1120" y="900"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="580" y="900"/>
|
||||||
|
<p2 x="800" y="900"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="780" y="200"/>
|
<p1 x="780" y="200"/>
|
||||||
<p2 x="800" y="200"/>
|
<p2 x="800" y="200"/>
|
||||||
@ -856,6 +892,10 @@
|
|||||||
<p1 x="580" y="980"/>
|
<p1 x="580" y="980"/>
|
||||||
<p2 x="600" y="980"/>
|
<p2 x="600" y="980"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="760" y="980"/>
|
||||||
|
<p2 x="780" y="980"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="280" y="980"/>
|
<p1 x="280" y="980"/>
|
||||||
<p2 x="300" y="980"/>
|
<p2 x="300" y="980"/>
|
||||||
@ -1248,6 +1288,22 @@
|
|||||||
<p1 x="1160" y="440"/>
|
<p1 x="1160" y="440"/>
|
||||||
<p2 x="1200" y="440"/>
|
<p2 x="1200" y="440"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="740" y="1020"/>
|
||||||
|
<p2 x="760" y="1020"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="280" y="1020"/>
|
||||||
|
<p2 x="300" y="1020"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="580" y="1020"/>
|
||||||
|
<p2 x="600" y="1020"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="760" y="1020"/>
|
||||||
|
<p2 x="840" y="1020"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="940" y="700"/>
|
<p1 x="940" y="700"/>
|
||||||
<p2 x="960" y="700"/>
|
<p2 x="960" y="700"/>
|
||||||
@ -1272,14 +1328,6 @@
|
|||||||
<p1 x="940" y="380"/>
|
<p1 x="940" y="380"/>
|
||||||
<p2 x="960" y="380"/>
|
<p2 x="960" y="380"/>
|
||||||
</wire>
|
</wire>
|
||||||
<wire>
|
|
||||||
<p1 x="280" y="1020"/>
|
|
||||||
<p2 x="300" y="1020"/>
|
|
||||||
</wire>
|
|
||||||
<wire>
|
|
||||||
<p1 x="580" y="1020"/>
|
|
||||||
<p2 x="600" y="1020"/>
|
|
||||||
</wire>
|
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="640" y="500"/>
|
<p1 x="640" y="500"/>
|
||||||
<p2 x="640" y="520"/>
|
<p2 x="640" y="520"/>
|
||||||
@ -1330,7 +1378,7 @@
|
|||||||
</wire>
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="580" y="860"/>
|
<p1 x="580" y="860"/>
|
||||||
<p2 x="580" y="920"/>
|
<p2 x="580" y="900"/>
|
||||||
</wire>
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="580" y="360"/>
|
<p1 x="580" y="360"/>
|
||||||
@ -1340,6 +1388,10 @@
|
|||||||
<p1 x="580" y="380"/>
|
<p1 x="580" y="380"/>
|
||||||
<p2 x="580" y="420"/>
|
<p2 x="580" y="420"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="580" y="900"/>
|
||||||
|
<p2 x="580" y="920"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="580" y="920"/>
|
<p1 x="580" y="920"/>
|
||||||
<p2 x="580" y="940"/>
|
<p2 x="580" y="940"/>
|
||||||
@ -1452,6 +1504,10 @@
|
|||||||
<p1 x="520" y="740"/>
|
<p1 x="520" y="740"/>
|
||||||
<p2 x="520" y="780"/>
|
<p2 x="520" y="780"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="840" y="960"/>
|
||||||
|
<p2 x="840" y="1020"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="460" y="560"/>
|
<p1 x="460" y="560"/>
|
||||||
<p2 x="460" y="580"/>
|
<p2 x="460" y="580"/>
|
||||||
@ -1640,6 +1696,10 @@
|
|||||||
<p1 x="1120" y="960"/>
|
<p1 x="1120" y="960"/>
|
||||||
<p2 x="1120" y="980"/>
|
<p2 x="1120" y="980"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="800" y="900"/>
|
||||||
|
<p2 x="800" y="940"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="360" y="100"/>
|
<p1 x="360" y="100"/>
|
||||||
<p2 x="360" y="760"/>
|
<p2 x="360" y="760"/>
|
||||||
@ -1789,12 +1849,8 @@
|
|||||||
<p2 x="500" y="840"/>
|
<p2 x="500" y="840"/>
|
||||||
</wire>
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="440" y="560"/>
|
<p1 x="760" y="960"/>
|
||||||
<p2 x="440" y="580"/>
|
<p2 x="760" y="980"/>
|
||||||
</wire>
|
|
||||||
<wire>
|
|
||||||
<p1 x="440" y="400"/>
|
|
||||||
<p2 x="440" y="420"/>
|
|
||||||
</wire>
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="760" y="220"/>
|
<p1 x="760" y="220"/>
|
||||||
@ -1812,6 +1868,18 @@
|
|||||||
<p1 x="760" y="400"/>
|
<p1 x="760" y="400"/>
|
||||||
<p2 x="760" y="600"/>
|
<p2 x="760" y="600"/>
|
||||||
</wire>
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="760" y="980"/>
|
||||||
|
<p2 x="760" y="1020"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="440" y="560"/>
|
||||||
|
<p2 x="440" y="580"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="440" y="400"/>
|
||||||
|
<p2 x="440" y="420"/>
|
||||||
|
</wire>
|
||||||
<wire>
|
<wire>
|
||||||
<p1 x="1080" y="180"/>
|
<p1 x="1080" y="180"/>
|
||||||
<p2 x="1080" y="320"/>
|
<p2 x="1080" y="320"/>
|
||||||
|
182
src/test/resources/dig/test/pinControl/simple.dig
Normal file
182
src/test/resources/dig/test/pinControl/simple.dig
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<circuit>
|
||||||
|
<version>1</version>
|
||||||
|
<attributes/>
|
||||||
|
<visualElements>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>wr_0</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="360" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>oe</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="360" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>PinControl</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="380" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>rotation</string>
|
||||||
|
<rotation rotation="2"/>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>rd_0</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="360" y="220"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>rotation</string>
|
||||||
|
<rotation rotation="2"/>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>wr_1</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="540" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>PinControl</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>mirror</string>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>rotation</string>
|
||||||
|
<rotation rotation="2"/>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="520" y="180"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>rd_1</string>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Bits</string>
|
||||||
|
<int>4</int>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="540" y="220"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Not</elementName>
|
||||||
|
<elementAttributes/>
|
||||||
|
<pos x="420" y="140"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Testcase</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Testdata</string>
|
||||||
|
<testData>
|
||||||
|
<dataString>oe wr_0 rd_0 wr_1 rd_1
|
||||||
|
1 1 x x 1
|
||||||
|
1 2 x x 2
|
||||||
|
0 x 1 1 x
|
||||||
|
0 x 2 2 x
|
||||||
|
</dataString>
|
||||||
|
</testData>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="400" y="240"/>
|
||||||
|
</visualElement>
|
||||||
|
</visualElements>
|
||||||
|
<wires>
|
||||||
|
<wire>
|
||||||
|
<p1 x="520" y="180"/>
|
||||||
|
<p2 x="540" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="180"/>
|
||||||
|
<p2 x="380" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="440" y="180"/>
|
||||||
|
<p2 x="460" y="180"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="460" y="140"/>
|
||||||
|
<p2 x="500" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="140"/>
|
||||||
|
<p2 x="400" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="400" y="140"/>
|
||||||
|
<p2 x="420" y="140"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="360" y="220"/>
|
||||||
|
<p2 x="420" y="220"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="480" y="220"/>
|
||||||
|
<p2 x="540" y="220"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="480" y="200"/>
|
||||||
|
<p2 x="480" y="220"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="400" y="140"/>
|
||||||
|
<p2 x="400" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="420" y="200"/>
|
||||||
|
<p2 x="420" y="220"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="500" y="140"/>
|
||||||
|
<p2 x="500" y="160"/>
|
||||||
|
</wire>
|
||||||
|
</wires>
|
||||||
|
<measurementOrdering/>
|
||||||
|
</circuit>
|
98
src/test/resources/dig/test/pinControl/uniTest.dig
Normal file
98
src/test/resources/dig/test/pinControl/uniTest.dig
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<circuit>
|
||||||
|
<version>1</version>
|
||||||
|
<attributes/>
|
||||||
|
<visualElements>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>wr</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="340" y="200"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>In</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>oe</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="340" y="160"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>PinControl</elementName>
|
||||||
|
<elementAttributes/>
|
||||||
|
<pos x="360" y="200"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>rotation</string>
|
||||||
|
<rotation rotation="2"/>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>rd</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="340" y="240"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Out</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Label</string>
|
||||||
|
<string>pin</string>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="440" y="200"/>
|
||||||
|
</visualElement>
|
||||||
|
<visualElement>
|
||||||
|
<elementName>Testcase</elementName>
|
||||||
|
<elementAttributes>
|
||||||
|
<entry>
|
||||||
|
<string>Testdata</string>
|
||||||
|
<testData>
|
||||||
|
<dataString>oe wr rd pin
|
||||||
|
1 0 0 0
|
||||||
|
1 1 1 1
|
||||||
|
</dataString>
|
||||||
|
</testData>
|
||||||
|
</entry>
|
||||||
|
</elementAttributes>
|
||||||
|
<pos x="360" y="240"/>
|
||||||
|
</visualElement>
|
||||||
|
</visualElements>
|
||||||
|
<wires>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="240"/>
|
||||||
|
<p2 x="400" y="240"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="160"/>
|
||||||
|
<p2 x="380" y="160"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="340" y="200"/>
|
||||||
|
<p2 x="360" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="420" y="200"/>
|
||||||
|
<p2 x="440" y="200"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="400" y="220"/>
|
||||||
|
<p2 x="400" y="240"/>
|
||||||
|
</wire>
|
||||||
|
<wire>
|
||||||
|
<p1 x="380" y="160"/>
|
||||||
|
<p2 x="380" y="180"/>
|
||||||
|
</wire>
|
||||||
|
</wires>
|
||||||
|
<measurementOrdering/>
|
||||||
|
</circuit>
|
Loading…
x
Reference in New Issue
Block a user