mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-22 20:01:09 -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(Terminal.DESCRIPTION)
|
||||
.add(VGA.DESCRIPTION)
|
||||
.add(MIDI.DESCRIPTION)))
|
||||
.add(MIDI.DESCRIPTION)
|
||||
.add(PinControl.DESCRIPTION)))
|
||||
.add(new LibraryNode(Lang.get("lib_wires"))
|
||||
.add(Ground.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(PullUp.DESCRIPTION.getName(), PullUpShape::new);
|
||||
map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new);
|
||||
map.put(PinControl.DESCRIPTION.getName(), PinControlShape::new);
|
||||
|
||||
// disables string formatting for external components, see #272
|
||||
map.put(External.DESCRIPTION.getName(),
|
||||
|
@ -44,6 +44,7 @@ import java.util.*;
|
||||
*/
|
||||
public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Printable {
|
||||
private final String elementName;
|
||||
private final int depth;
|
||||
private final ArrayList<HDLPort> outputs;
|
||||
private final ArrayList<HDLPort> inputs;
|
||||
private final ArrayList<HDLNet> listOfNets;
|
||||
@ -61,12 +62,13 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
||||
* @param circuit the circuit
|
||||
* @param elementName the name of the circuit
|
||||
* @param c the context to create the circuits
|
||||
* @param depth the depth of this circuit in the circuits hierarchy
|
||||
* @throws PinException PinException
|
||||
* @throws HDLException HDLException
|
||||
* @throws NodeException NodeException
|
||||
*/
|
||||
HDLCircuit(Circuit circuit, String elementName, HDLModel c) throws PinException, HDLException, NodeException {
|
||||
this(circuit, elementName, c, null);
|
||||
HDLCircuit(Circuit circuit, String elementName, HDLModel c, int depth) throws PinException, HDLException, NodeException {
|
||||
this(circuit, elementName, c, depth, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,13 +77,15 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
||||
* @param circuit the circuit
|
||||
* @param elementName the name of the circuit
|
||||
* @param c the context to create the circuits
|
||||
* @param depth the depth of this circuit in the circuits hierarchy
|
||||
* @param clockIntegrator the clock integrator
|
||||
* @throws PinException PinException
|
||||
* @throws HDLException HDLException
|
||||
* @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.depth = depth;
|
||||
|
||||
if (elementName.toLowerCase().endsWith(".dig"))
|
||||
hdlEntityName = elementName.substring(0, elementName.length() - 4);
|
||||
@ -154,12 +158,18 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
||||
nodes.addAll(newNodes);
|
||||
|
||||
for (HDLPort i : inputs)
|
||||
if (i.getNet() != null)
|
||||
if (i.getNet() != null) {
|
||||
i.getNet().setIsInput(i.getName());
|
||||
if (i.getNet().isInOutNet())
|
||||
i.setInOut();
|
||||
}
|
||||
|
||||
for (HDLPort o : outputs)
|
||||
for (HDLPort o : outputs) {
|
||||
if (o.getNet().needsVariable())
|
||||
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 the depth of this circuit in the circuits hierarchy
|
||||
*/
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.core.element.PinDescription;
|
||||
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.core.io.*;
|
||||
import de.neemann.digital.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.Pin;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
@ -77,7 +73,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
||||
if (c == null) {
|
||||
String elementName = v.getElementName();
|
||||
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());
|
||||
circuitMap.put(holder.getCircuit(), c);
|
||||
}
|
||||
@ -90,7 +86,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
||||
HDLCircuit c = circuitMap.get(circuit);
|
||||
final String elementName = cleanName(v.getElementName());
|
||||
if (c == null) {
|
||||
c = new HDLCircuit(circuit, elementName, this);
|
||||
c = new HDLCircuit(circuit, elementName, this, parent.getDepth() + 1);
|
||||
circuitMap.put(circuit, c);
|
||||
}
|
||||
|
||||
@ -151,7 +147,6 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
||||
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||
v, parent).createExpressions();
|
||||
|
||||
|
||||
} catch (ElementNotFoundException | PinException | NodeException 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 {
|
||||
for (Pin p : v.getPins()) {
|
||||
HDLNet net = c.getNetOfPin(p);
|
||||
if (p.getDirection().equals(PinDescription.Direction.input))
|
||||
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
||||
else
|
||||
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
||||
switch (p.getDirection()) {
|
||||
case input:
|
||||
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
||||
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;
|
||||
}
|
||||
@ -205,7 +212,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
||||
* @throws NodeException 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);
|
||||
return this;
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class HDLNet implements Printable, HasName {
|
||||
private final boolean userNamed;
|
||||
private final ArrayList<HDLPort> inputs;
|
||||
private final ArrayList<HDLPort> inOutputs;
|
||||
private String name;
|
||||
private ArrayList<HDLPort> inputs;
|
||||
private HDLPort output;
|
||||
private boolean needsVariable = true;
|
||||
private boolean isInput;
|
||||
@ -32,6 +33,7 @@ public class HDLNet implements Printable, HasName {
|
||||
public HDLNet(String name) {
|
||||
this.name = name;
|
||||
inputs = new ArrayList<>();
|
||||
inOutputs = new ArrayList<>();
|
||||
userNamed = name != null;
|
||||
}
|
||||
|
||||
@ -49,16 +51,23 @@ public class HDLNet implements Printable, HasName {
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public void addPort(HDLPort hdlPort) throws HDLException {
|
||||
if (hdlPort.getDirection().equals(HDLPort.Direction.OUT)) {
|
||||
if (output != null) {
|
||||
String netName = name;
|
||||
if (netName == null)
|
||||
netName = Lang.get("err_unnamedNet");
|
||||
throw new HDLException(Lang.get("err_hdlMultipleOutputsConnectedToNet_N_N_N", netName, output, hdlPort));
|
||||
}
|
||||
output = hdlPort;
|
||||
} else
|
||||
inputs.add(hdlPort);
|
||||
switch (hdlPort.getDirection()) {
|
||||
case OUT:
|
||||
if (output != null) {
|
||||
String netName = name;
|
||||
if (netName == null)
|
||||
netName = Lang.get("err_unnamedNet");
|
||||
throw new HDLException(Lang.get("err_hdlMultipleOutputsConnectedToNet_N_N_N", netName, output, hdlPort));
|
||||
}
|
||||
output = 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 {
|
||||
if (output == null)
|
||||
throw new HDLException("no output connected to net");
|
||||
final int bits = output.getBits();
|
||||
if (bits == 0)
|
||||
throw new HDLException("no bit number set for output " + output.getName());
|
||||
int bits = 0;
|
||||
if (output == null) {
|
||||
if (inOutputs.isEmpty())
|
||||
throw new HDLException("no output connected to net");
|
||||
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)
|
||||
i.setBits(bits);
|
||||
@ -96,6 +119,8 @@ public class HDLNet implements Printable, HasName {
|
||||
* @return the constant if this net is a constant, null otherwise
|
||||
*/
|
||||
public ExprConstant isConstant() {
|
||||
if (output == null)
|
||||
return null;
|
||||
return ExprConstant.isConstant(output.getParent());
|
||||
}
|
||||
|
||||
@ -160,9 +185,18 @@ public class HDLNet implements Printable, HasName {
|
||||
|
||||
/**
|
||||
* @return the number of bits on this net
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public int getBits() {
|
||||
return output.getBits();
|
||||
public int getBits() throws HDLException {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 ArrayList<HDLPort> inputs;
|
||||
private final ArrayList<HDLPort> outputs;
|
||||
private final ArrayList<HDLPort> inOutputs;
|
||||
private String hdlEntityName;
|
||||
|
||||
/**
|
||||
@ -37,6 +38,7 @@ public abstract class HDLNode {
|
||||
this.bitProvider = bitProvider;
|
||||
inputs = new ArrayList<>();
|
||||
outputs = new ArrayList<>();
|
||||
inOutputs = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,10 +48,17 @@ public abstract class HDLNode {
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public HDLNode addPort(HDLPort port) {
|
||||
if (port.getDirection().equals(HDLPort.Direction.OUT))
|
||||
outputs.add(port);
|
||||
else
|
||||
inputs.add(port);
|
||||
switch (port.getDirection()) {
|
||||
case IN:
|
||||
inputs.add(port);
|
||||
break;
|
||||
case OUT:
|
||||
outputs.add(port);
|
||||
break;
|
||||
case INOUT:
|
||||
inOutputs.add(port);
|
||||
break;
|
||||
}
|
||||
|
||||
port.setParent(this);
|
||||
|
||||
@ -96,6 +105,13 @@ public abstract class HDLNode {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of inOutputs
|
||||
*/
|
||||
public ArrayList<HDLPort> getInOutputs() {
|
||||
return inOutputs;
|
||||
}
|
||||
|
||||
int getBits(String name) {
|
||||
return bitProvider.getBits(name);
|
||||
}
|
||||
@ -111,6 +127,10 @@ public abstract class HDLNode {
|
||||
printWithLocal(out, inputs);
|
||||
out.print("out");
|
||||
printWithLocal(out, outputs);
|
||||
if (!inOutputs.isEmpty()) {
|
||||
out.print("inOut");
|
||||
printWithLocal(out, inOutputs);
|
||||
}
|
||||
}
|
||||
|
||||
private void printWithLocal(CodePrinter out, ArrayList<HDLPort> ports) throws IOException {
|
||||
@ -177,6 +197,8 @@ public abstract class HDLNode {
|
||||
p.rename(renaming);
|
||||
for (HDLPort p : inputs)
|
||||
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,
|
||||
* seen from inside the node.
|
||||
*/
|
||||
OUT
|
||||
OUT,
|
||||
/**
|
||||
* Bidirectional port
|
||||
*/
|
||||
INOUT
|
||||
}
|
||||
|
||||
private String name;
|
||||
private final Direction direction;
|
||||
private Direction direction;
|
||||
private int bits;
|
||||
private String description;
|
||||
private boolean isClock;
|
||||
@ -213,4 +217,11 @@ public class HDLPort implements Printable, HasName {
|
||||
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
|
||||
*
|
||||
* @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
|
||||
* @return the verilog signal type
|
||||
*/
|
||||
public static String getType(HDLPort.Direction dir, int bits) {
|
||||
String result = (dir == HDLPort.Direction.IN) ? "input" : "output";
|
||||
public static String getType(HDLPort.Direction def, HDLPort.Direction dir, int bits) {
|
||||
String result;
|
||||
if (dir == HDLPort.Direction.INOUT)
|
||||
result = "inout";
|
||||
else
|
||||
result = (def == HDLPort.Direction.IN) ? "input" : "output";
|
||||
|
||||
if (bits > 1) {
|
||||
result += " [" + (bits - 1) + ":0]";
|
||||
@ -181,12 +186,12 @@ public class VerilogCreator {
|
||||
|
||||
for (HDLPort i : circuit.getInputs()) {
|
||||
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()));
|
||||
}
|
||||
for (HDLPort o : circuit.getOutputs()) {
|
||||
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()));
|
||||
}
|
||||
sep.close();
|
||||
@ -260,6 +265,12 @@ public class VerilogCreator {
|
||||
sep.check();
|
||||
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.println().println(");");
|
||||
}
|
||||
|
@ -178,18 +178,24 @@ public class VHDLCreator {
|
||||
|
||||
for (HDLPort i : circuit.getInputs()) {
|
||||
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()));
|
||||
}
|
||||
for (HDLPort o : circuit.getOutputs()) {
|
||||
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()));
|
||||
}
|
||||
sep.close();
|
||||
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 {
|
||||
String target = node.getTargetSignal();
|
||||
|
||||
@ -250,6 +256,11 @@ public class VHDLCreator {
|
||||
sep.check();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -338,25 +338,47 @@
|
||||
<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>
|
||||
<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.
|
||||
Ist der sel Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht.
|
||||
Ist der Eingang 1, ist der Ausgang hochohmig.
|
||||
</string>
|
||||
<string name="elem_DriverInvSel_pin_in">Das Eingangssignal des Treibers.</string>
|
||||
<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>
|
||||
<string name="elem_DriverInvSel_pin_out">Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0 gesetzt ist.</string>
|
||||
Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1,
|
||||
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 -->
|
||||
|
||||
<string name="elem_Multiplexer">Multiplexer</string>
|
||||
<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_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_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>
|
||||
|
@ -363,11 +363,26 @@
|
||||
If the sel input is 1, this output is in high z state.
|
||||
</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 -->
|
||||
|
||||
<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_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>
|
||||
|
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 {
|
||||
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 {
|
||||
|
@ -26,7 +26,7 @@ public class DescriptionTest extends TestCase {
|
||||
br.getCircuit(),
|
||||
"main"
|
||||
, new HDLModel(br.getLibrary()),
|
||||
null)
|
||||
0, null)
|
||||
.applyDefaultOptimizations();
|
||||
CodePrinterStr out = new CodePrinterStr();
|
||||
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.hdl.model2.HDLException;
|
||||
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.Resources;
|
||||
import de.neemann.digital.integration.TestExamples;
|
||||
@ -42,13 +43,13 @@ public class VerilogSimulatorTest extends TestCase {
|
||||
|
||||
/*
|
||||
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);
|
||||
System.out.println(new VerilogGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
|
||||
|
||||
checkVerilogExport(file);
|
||||
}*/
|
||||
}/**/
|
||||
|
||||
public void testInSimulator() throws Exception {
|
||||
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 {
|
||||
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
||||
try {
|
||||
@ -128,7 +144,7 @@ public class VerilogSimulatorTest extends TestCase {
|
||||
try {
|
||||
File srcFile = new File(dir, file.getName()
|
||||
.replace('.', '_')
|
||||
.replace('-', '_')+ ".v");
|
||||
.replace('-', '_') + ".v");
|
||||
CodePrinter out = new CodePrinter(srcFile);
|
||||
try (VerilogGenerator gen = new VerilogGenerator(br.getLibrary(), out)) {
|
||||
gen.export(br.getCircuit());
|
||||
|
@ -123,7 +123,7 @@ public class ClockTest extends TestCase {
|
||||
HDLCircuit c = new HDLCircuit(
|
||||
br.getCircuit(), "main",
|
||||
new HDLModel(br.getLibrary()),
|
||||
ci);
|
||||
0, ci);
|
||||
|
||||
c.applyDefaultOptimizations();
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class DescriptionTest extends TestCase {
|
||||
br.getCircuit(),
|
||||
"main"
|
||||
, new HDLModel(br.getLibrary()),
|
||||
null)
|
||||
0, null)
|
||||
.applyDefaultOptimizations();
|
||||
CodePrinterStr out = new CodePrinterStr();
|
||||
new VHDLCreator(out, br.getLibrary()).printHDLCircuit(circuit);
|
||||
|
@ -34,7 +34,7 @@ public class VHDLSimulatorTest extends TestCase {
|
||||
|
||||
/*
|
||||
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);
|
||||
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 {
|
||||
File examples = new File(Resources.getRoot(), "../../main/dig/hdl");
|
||||
try {
|
||||
|
@ -43,8 +43,8 @@ public class TestExamples extends TestCase {
|
||||
*/
|
||||
public void testTestExamples() throws Exception {
|
||||
File examples = new File(Resources.getRoot(), "/dig/test");
|
||||
assertEquals(184, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(172, testCasesInFiles);
|
||||
assertEquals(186, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(174, testCasesInFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -614,6 +614,30 @@
|
||||
<elementAttributes/>
|
||||
<pos x="600" y="920"/>
|
||||
</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>
|
||||
<wires>
|
||||
<wire>
|
||||
@ -668,6 +692,14 @@
|
||||
<p1 x="580" y="960"/>
|
||||
<p2 x="600" y="960"/>
|
||||
</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>
|
||||
<p1 x="240" y="260"/>
|
||||
<p2 x="260" y="260"/>
|
||||
@ -716,6 +748,10 @@
|
||||
<p1 x="1080" y="900"/>
|
||||
<p2 x="1120" y="900"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="580" y="900"/>
|
||||
<p2 x="800" y="900"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="780" y="200"/>
|
||||
<p2 x="800" y="200"/>
|
||||
@ -856,6 +892,10 @@
|
||||
<p1 x="580" y="980"/>
|
||||
<p2 x="600" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="760" y="980"/>
|
||||
<p2 x="780" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="980"/>
|
||||
<p2 x="300" y="980"/>
|
||||
@ -1248,6 +1288,22 @@
|
||||
<p1 x="1160" y="440"/>
|
||||
<p2 x="1200" y="440"/>
|
||||
</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>
|
||||
<p1 x="940" y="700"/>
|
||||
<p2 x="960" y="700"/>
|
||||
@ -1272,14 +1328,6 @@
|
||||
<p1 x="940" y="380"/>
|
||||
<p2 x="960" y="380"/>
|
||||
</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="640" y="500"/>
|
||||
<p2 x="640" y="520"/>
|
||||
@ -1330,7 +1378,7 @@
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="580" y="860"/>
|
||||
<p2 x="580" y="920"/>
|
||||
<p2 x="580" y="900"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="580" y="360"/>
|
||||
@ -1340,6 +1388,10 @@
|
||||
<p1 x="580" y="380"/>
|
||||
<p2 x="580" y="420"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="580" y="900"/>
|
||||
<p2 x="580" y="920"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="580" y="920"/>
|
||||
<p2 x="580" y="940"/>
|
||||
@ -1452,6 +1504,10 @@
|
||||
<p1 x="520" y="740"/>
|
||||
<p2 x="520" y="780"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="840" y="960"/>
|
||||
<p2 x="840" y="1020"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="560"/>
|
||||
<p2 x="460" y="580"/>
|
||||
@ -1640,6 +1696,10 @@
|
||||
<p1 x="1120" y="960"/>
|
||||
<p2 x="1120" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="800" y="900"/>
|
||||
<p2 x="800" y="940"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="100"/>
|
||||
<p2 x="360" y="760"/>
|
||||
@ -1789,12 +1849,8 @@
|
||||
<p2 x="500" y="840"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="560"/>
|
||||
<p2 x="440" y="580"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="400"/>
|
||||
<p2 x="440" y="420"/>
|
||||
<p1 x="760" y="960"/>
|
||||
<p2 x="760" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="760" y="220"/>
|
||||
@ -1812,6 +1868,18 @@
|
||||
<p1 x="760" y="400"/>
|
||||
<p2 x="760" y="600"/>
|
||||
</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>
|
||||
<p1 x="1080" y="180"/>
|
||||
<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