mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -04:00
most of the optimizations are working, splitter is still missing
This commit is contained in:
parent
8811863b12
commit
cb1266e35e
@ -277,6 +277,9 @@ public class Net {
|
||||
return visualElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the set of labels attached to this net
|
||||
*/
|
||||
public HashSet<String> getLabels() {
|
||||
return labelSet;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.basic.Not;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.core.element.PinDescription;
|
||||
import de.neemann.digital.core.io.In;
|
||||
import de.neemann.digital.core.io.Out;
|
||||
import de.neemann.digital.core.io.PowerSupply;
|
||||
@ -23,22 +22,34 @@ import de.neemann.digital.draw.model.InverterConfig;
|
||||
import de.neemann.digital.draw.model.Net;
|
||||
import de.neemann.digital.draw.model.NetList;
|
||||
import de.neemann.digital.gui.components.data.DummyElement;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
import de.neemann.digital.testing.TestCaseElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
/**
|
||||
* The representation of a circuit
|
||||
*/
|
||||
public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider, Printable {
|
||||
private final String elementName;
|
||||
private final ArrayList<HDLPort> outputs;
|
||||
private final ArrayList<HDLPort> inputs;
|
||||
private final ArrayList<HDLNet> listOfNets;
|
||||
private NetList netList;
|
||||
private ArrayList<HDLNode> nodes;
|
||||
private HashMap<Net, HDLNet> nets;
|
||||
private int netNumber;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param circuit the circuit
|
||||
* @param elementName the name of the circuit
|
||||
* @param c the context to create the circuits
|
||||
* @throws PinException PinException
|
||||
* @throws HDLException HDLException
|
||||
* @throws NodeException NodeException
|
||||
*/
|
||||
public HDLCircuit(Circuit circuit, String elementName, HDLContext c) throws PinException, HDLException, NodeException {
|
||||
this.elementName = elementName;
|
||||
inputs = new ArrayList<>();
|
||||
@ -64,7 +75,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
v.getElementAttributes().getBits())
|
||||
.setPinNumber(v.getElementAttributes().get(Keys.PINNUMBER)));
|
||||
else if (isRealElement(v))
|
||||
addNode(v, c);
|
||||
nodes.add(c.createNode(v, this));
|
||||
}
|
||||
} catch (HDLException e) {
|
||||
throw new HDLException("error parsing " + circuit.getOrigin(), e);
|
||||
@ -89,6 +100,19 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
}
|
||||
|
||||
nodes.addAll(newNodes);
|
||||
|
||||
listOfNets = new ArrayList<>();
|
||||
listOfNets.addAll(nets.values());
|
||||
|
||||
nets = null;
|
||||
|
||||
for (HDLPort i : inputs)
|
||||
i.getNet().setIsInput(i.getName());
|
||||
|
||||
for (HDLPort o : outputs)
|
||||
if (o.getNet().needsVariable())
|
||||
o.getNet().setIsOutput(o.getName(), o.getNet().getInputs().size() == 1);
|
||||
|
||||
}
|
||||
|
||||
private HDLNode createNot(HDLPort p) throws HDLException, NodeException, PinException {
|
||||
@ -126,7 +150,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
&& !v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION);
|
||||
}
|
||||
|
||||
private HDLNet getNetOfPin(Pin pin) {
|
||||
HDLNet getNetOfPin(Pin pin) {
|
||||
Net n = netList.getNetOfPos(pin.getPos());
|
||||
if (n == null)
|
||||
return null;
|
||||
@ -139,19 +163,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
if (labels.size() == 1)
|
||||
return labels.iterator().next();
|
||||
else
|
||||
return Integer.toString(netNumber++);
|
||||
}
|
||||
|
||||
private void addNode(VisualElement v, HDLContext c) throws HDLException {
|
||||
final HDLNode node = c.createNode(v);
|
||||
for (Pin p : v.getPins()) {
|
||||
HDLNet net = getNetOfPin(p);
|
||||
if (p.getDirection().equals(PinDescription.Direction.input))
|
||||
node.addInput(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
||||
else
|
||||
node.addOutput(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
||||
}
|
||||
nodes.add(node);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -167,18 +179,32 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the elements name
|
||||
*/
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the circuits outputs
|
||||
*/
|
||||
public ArrayList<HDLPort> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the circuits inputs
|
||||
*/
|
||||
public ArrayList<HDLPort> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses all the nodes
|
||||
*
|
||||
* @param visitor the visitor to use
|
||||
*/
|
||||
public void traverse(HDLVisitor visitor) {
|
||||
for (HDLNode n : nodes)
|
||||
n.traverse(visitor);
|
||||
@ -188,4 +214,109 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
||||
public String toString() {
|
||||
return "HDLCircuit{elementName='" + elementName + "'}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges logcal operations if possible
|
||||
*
|
||||
* @return this for chained calls
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public HDLCircuit mergeOperations() throws HDLException {
|
||||
nodes = new OperationMerger(nodes, this).merge();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name the unnamed nets
|
||||
*
|
||||
* @param netNamer the net naming algorithm
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public HDLCircuit nameNets(NetNamer netNamer) {
|
||||
for (HDLNet n : listOfNets)
|
||||
if (n.getName() == null)
|
||||
n.setName(netNamer.createName(n));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print("circuit ").println(elementName).inc();
|
||||
out.print("in");
|
||||
printList(out, inputs);
|
||||
out.print("out");
|
||||
printList(out, outputs);
|
||||
out.print("sig");
|
||||
printList(out, listOfNets);
|
||||
|
||||
out.println();
|
||||
for (HDLNode n : nodes) {
|
||||
out.print("node ").println(n.getElementName()).inc();
|
||||
n.print(out);
|
||||
out.dec();
|
||||
}
|
||||
out.println();
|
||||
for (HDLPort p : outputs) {
|
||||
final HDLNet net = p.getNet();
|
||||
if (net.needsVariable() || net.isInput()) {
|
||||
p.print(out);
|
||||
out.print(" := ");
|
||||
net.print(out);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
out.dec().print("end circuit ").println(elementName);
|
||||
}
|
||||
|
||||
private void printList(CodePrinter out, Collection<? extends Printable> ports) throws IOException {
|
||||
boolean first = true;
|
||||
for (Printable p : ports) {
|
||||
if (first) {
|
||||
first = false;
|
||||
out.print("(");
|
||||
} else
|
||||
out.print(", ");
|
||||
p.print(out);
|
||||
}
|
||||
out.println(")");
|
||||
}
|
||||
|
||||
private void printList(CodePrinter out, ArrayList<HDLNet> nets) throws IOException {
|
||||
boolean first = true;
|
||||
for (HDLNet net : nets) {
|
||||
if (net.needsVariable()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
out.print("(");
|
||||
} else
|
||||
out.print(", ");
|
||||
net.print(out);
|
||||
}
|
||||
}
|
||||
out.println(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed an obsolete net
|
||||
*
|
||||
* @param net the net to remove
|
||||
*/
|
||||
public void removeNet(HDLNet net) {
|
||||
listOfNets.remove(net);
|
||||
}
|
||||
|
||||
/**
|
||||
* The net naming algorithm
|
||||
*/
|
||||
public interface NetNamer {
|
||||
/**
|
||||
* Returns a nem for the given net
|
||||
*
|
||||
* @param n the net to name
|
||||
* @return the name to use
|
||||
*/
|
||||
String createName(HDLNet n);
|
||||
}
|
||||
}
|
||||
|
@ -7,26 +7,50 @@ package de.neemann.digital.hdl.model2;
|
||||
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValues;
|
||||
import de.neemann.digital.core.element.Element;
|
||||
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.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.Pin;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.hdl.model2.expression.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class HDLContext {
|
||||
/**
|
||||
* The context of creating nodes and circuits.
|
||||
* Ensures that every circuit is only processed one time.
|
||||
*/
|
||||
public class HDLContext implements Iterable<HDLCircuit> {
|
||||
private ElementLibrary elementLibrary;
|
||||
private HashMap<Circuit, HDLCircuit> circuitMap;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param elementLibrary the element library
|
||||
*/
|
||||
public HDLContext(ElementLibrary elementLibrary) {
|
||||
this.elementLibrary = elementLibrary;
|
||||
circuitMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public HDLNode createNode(VisualElement v) throws HDLException {
|
||||
/**
|
||||
* Creates a isolated node
|
||||
*
|
||||
* @param v the VisualElement of the node
|
||||
* @param parent the parrents circuit
|
||||
* @return the node
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public HDLNode createNode(VisualElement v, HDLCircuit parent) throws HDLException {
|
||||
try {
|
||||
ElementTypeDescription td = elementLibrary.getElementType(v.getElementName());
|
||||
if (td instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
@ -38,26 +62,106 @@ public class HDLContext {
|
||||
circuitMap.put(tdc.getCircuit(), c);
|
||||
}
|
||||
|
||||
return new HDLNodeCustom(v.getElementName(), v.getElementAttributes(), c);
|
||||
return addInputsOutputs(
|
||||
new HDLNodeCustom(v.getElementName(), v.getElementAttributes(), c),
|
||||
v, parent);
|
||||
|
||||
} else if (v.equalsDescription(Const.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(new ExprConstant(node.getElementAttributes().get(Keys.VALUE), node.getOutput().getBits()));
|
||||
return node;
|
||||
} else if (v.equalsDescription(Not.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(new ExprNot(new ExprVar(node.getInputs().get(0).getNet())));
|
||||
return node;
|
||||
} else if (v.equalsDescription(Or.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(createOperation(node.getInputs(), ExprOperate.Operation.OR));
|
||||
return node;
|
||||
} else if (v.equalsDescription(And.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(createOperation(node.getInputs(), ExprOperate.Operation.AND));
|
||||
return node;
|
||||
} else if (v.equalsDescription(XOr.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(createOperation(node.getInputs(), ExprOperate.Operation.XOR));
|
||||
return node;
|
||||
} else if (v.equalsDescription(NOr.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(new ExprNot(createOperation(node.getInputs(), ExprOperate.Operation.OR)));
|
||||
return node;
|
||||
} else if (v.equalsDescription(NAnd.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(new ExprNot(createOperation(node.getInputs(), ExprOperate.Operation.AND)));
|
||||
return node;
|
||||
} else if (v.equalsDescription(XNOr.DESCRIPTION)) {
|
||||
final HDLNodeExpression node = createExpression(v, parent, td);
|
||||
node.setExpression(new ExprNot(createOperation(node.getInputs(), ExprOperate.Operation.XOR)));
|
||||
return node;
|
||||
} else
|
||||
return new HDLNode(v.getElementName(),
|
||||
v.getElementAttributes(),
|
||||
new ObserVableValuesBits(
|
||||
td.createElement(v.getElementAttributes()).getOutputs()));
|
||||
return addInputsOutputs(
|
||||
new HDLNode(v.getElementName(),
|
||||
v.getElementAttributes(),
|
||||
new ObservableValuesBitsProvider(
|
||||
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||
v, parent);
|
||||
|
||||
|
||||
} catch (ElementNotFoundException | PinException | NodeException e) {
|
||||
throw new HDLException("error creating node", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Expression createOperation(ArrayList<HDLPort> inputs, ExprOperate.Operation op) {
|
||||
ArrayList<Expression> list = new ArrayList<>();
|
||||
for (HDLPort p : inputs) {
|
||||
list.add(new ExprVar(p.getNet()));
|
||||
}
|
||||
return new ExprOperate(op, list);
|
||||
}
|
||||
|
||||
private HDLNodeExpression createExpression(VisualElement v, HDLCircuit parent, ElementTypeDescription td) throws HDLException, PinException {
|
||||
return addInputsOutputs(new HDLNodeExpression(v.getElementName(),
|
||||
v.getElementAttributes(),
|
||||
new ObservableValuesBitsProvider(
|
||||
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||
v, parent);
|
||||
}
|
||||
|
||||
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.addInput(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
|
||||
else
|
||||
node.addOutput(new HDLPort(p.getName(), net, HDLPort.Direction.OUT, node.getBits(p.getName())));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator<HDLCircuit> iterator() {
|
||||
return circuitMap.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bit provider interface
|
||||
*/
|
||||
public interface BitProvider {
|
||||
/**
|
||||
* Returns the number of bits of the signal with the given name
|
||||
*
|
||||
* @param name the signal name
|
||||
* @return the number of bits
|
||||
*/
|
||||
int getBits(String name);
|
||||
}
|
||||
|
||||
private class ObserVableValuesBits implements BitProvider {
|
||||
private static final class ObservableValuesBitsProvider implements BitProvider {
|
||||
private final ObservableValues values;
|
||||
|
||||
private ObserVableValuesBits(ObservableValues values) {
|
||||
private ObservableValuesBitsProvider(ObservableValues values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
|
@ -5,11 +5,25 @@
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2;
|
||||
|
||||
/**
|
||||
* Exception thrown during model building
|
||||
*/
|
||||
public class HDLException extends Exception {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param message the message
|
||||
* @param cause the cause
|
||||
*/
|
||||
public HDLException(String message, Exception cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param message the message
|
||||
*/
|
||||
public HDLException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
@ -5,18 +5,38 @@
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2;
|
||||
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HDLNet {
|
||||
/**
|
||||
* Represents a net.
|
||||
* A net can have only one input and several outputs.
|
||||
*/
|
||||
public class HDLNet implements Printable {
|
||||
private String name;
|
||||
private ArrayList<HDLPort> inputs;
|
||||
private HDLPort output;
|
||||
private boolean needsVariable = true;
|
||||
private boolean isInput;
|
||||
|
||||
/**
|
||||
* Creates a new net
|
||||
*
|
||||
* @param name the nets name
|
||||
*/
|
||||
public HDLNet(String name) {
|
||||
this.name = name;
|
||||
inputs = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a port to this net.
|
||||
*
|
||||
* @param hdlPort the port to add
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public void addPort(HDLPort hdlPort) throws HDLException {
|
||||
if (hdlPort.getDirection().equals(HDLPort.Direction.OUT)) {
|
||||
if (output != null)
|
||||
@ -26,12 +46,26 @@ public class HDLNet {
|
||||
inputs.add(hdlPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the inputs which are connected to this net.
|
||||
*/
|
||||
public ArrayList<HDLPort> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the output which defines the nets value
|
||||
*/
|
||||
public HDLPort getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " (" + output + " " + inputs + ")";
|
||||
}
|
||||
|
||||
public void fixBits() throws HDLException {
|
||||
void fixBits() throws HDLException {
|
||||
if (output == null)
|
||||
throw new HDLException("no output connected to net");
|
||||
final int bits = output.getBits();
|
||||
@ -43,7 +77,56 @@ public class HDLNet {
|
||||
|
||||
}
|
||||
|
||||
public void remove(HDLPort p) {
|
||||
void remove(HDLPort p) {
|
||||
inputs.remove(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print(name).print(":").print(output.getBits());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the net
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the net
|
||||
*
|
||||
* @param name the name to use
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
void setIsInput(String name) {
|
||||
this.needsVariable = false;
|
||||
this.isInput = true;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if tins net represents a nodes input
|
||||
*/
|
||||
public boolean isInput() {
|
||||
return isInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this net needs a temp variable to represent the value
|
||||
*/
|
||||
public boolean needsVariable() {
|
||||
return needsVariable;
|
||||
}
|
||||
|
||||
void setIsOutput(String name, boolean singleRead) {
|
||||
if (singleRead) {
|
||||
this.name = name;
|
||||
needsVariable = false;
|
||||
} else
|
||||
this.name = name + "_temp";
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,14 @@
|
||||
package de.neemann.digital.hdl.model2;
|
||||
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A node which represents a built-in component
|
||||
*/
|
||||
public class HDLNode {
|
||||
private final String elementName;
|
||||
private final ElementAttributes elementAttributes;
|
||||
@ -16,6 +21,13 @@ public class HDLNode {
|
||||
private final ArrayList<HDLPort> inputs;
|
||||
private final ArrayList<HDLPort> outputs;
|
||||
|
||||
/**
|
||||
* Creates e new intance
|
||||
*
|
||||
* @param elementName the instances name
|
||||
* @param elementAttributes the attributes
|
||||
* @param bitProvider the bit provider which provides the outputs bit width
|
||||
*/
|
||||
public HDLNode(String elementName, ElementAttributes elementAttributes, HDLContext.BitProvider bitProvider) {
|
||||
this.elementName = elementName;
|
||||
this.elementAttributes = elementAttributes;
|
||||
@ -24,14 +36,12 @@ public class HDLNode {
|
||||
outputs = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addInput(HDLPort port) {
|
||||
void addInput(HDLPort port) {
|
||||
inputs.add(port);
|
||||
port.setNode(this);
|
||||
}
|
||||
|
||||
public void addOutput(HDLPort port) {
|
||||
void addOutput(HDLPort port) {
|
||||
outputs.add(port);
|
||||
port.setNode(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -39,27 +49,99 @@ public class HDLNode {
|
||||
return elementName + " " + inputs + " " + outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the elements name
|
||||
*/
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the elements attributes
|
||||
*/
|
||||
public ElementAttributes getElementAttributes() {
|
||||
return elementAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodes inputs
|
||||
*/
|
||||
public ArrayList<HDLPort> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodes single outputs
|
||||
*/
|
||||
public HDLPort getOutput() {
|
||||
return outputs.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of outputs
|
||||
*/
|
||||
public ArrayList<HDLPort> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses all the nodes
|
||||
*
|
||||
* @param visitor the visitor to use
|
||||
*/
|
||||
public void traverse(HDLVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
public int getBits(String name) {
|
||||
int getBits(String name) {
|
||||
return bitProvider.getBits(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a simple text representation of the node
|
||||
*
|
||||
* @param out the CondePrinter to print to
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print("in");
|
||||
printWithLocal(out, inputs);
|
||||
out.print("out");
|
||||
printWithLocal(out, outputs);
|
||||
}
|
||||
|
||||
private void printWithLocal(CodePrinter out, ArrayList<HDLPort> ports) throws IOException {
|
||||
boolean first = true;
|
||||
for (HDLPort p : ports) {
|
||||
if (first) {
|
||||
first = false;
|
||||
out.print("(");
|
||||
} else
|
||||
out.print(", ");
|
||||
p.print(out);
|
||||
if (p.getNet() == null)
|
||||
out.print(" is not used");
|
||||
else {
|
||||
out.print(" is ");
|
||||
p.getNet().print(out);
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
out.println("(");
|
||||
|
||||
out.println(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node has the given port as an input
|
||||
*
|
||||
* @param i the port to search for
|
||||
* @return true if the given port is a input of this node
|
||||
*/
|
||||
public boolean hasInput(HDLPort i) {
|
||||
for (HDLPort p : inputs)
|
||||
if (p.getNet() == i.getNet())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,19 @@ package de.neemann.digital.hdl.model2;
|
||||
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
|
||||
/**
|
||||
* Represents a node which is build from a circuit.
|
||||
*/
|
||||
public class HDLNodeCustom extends HDLNode {
|
||||
private final HDLCircuit hdlCircuit;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param elementName the elements name
|
||||
* @param elementAttributes the attributes
|
||||
* @param hdlCircuit the circuit to use to create this node
|
||||
*/
|
||||
public HDLNodeCustom(String elementName, ElementAttributes elementAttributes, HDLCircuit hdlCircuit) {
|
||||
super(elementName, elementAttributes, hdlCircuit);
|
||||
this.hdlCircuit = hdlCircuit;
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2;
|
||||
|
||||
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A node which represents a simple expression
|
||||
*/
|
||||
public class HDLNodeExpression extends HDLNode {
|
||||
private Expression expression;
|
||||
|
||||
/**
|
||||
* Creates a new instace
|
||||
*
|
||||
* @param elementName the elements name
|
||||
* @param elementAttributes the attributes
|
||||
* @param bitProvider the bit provider which provides the outputs bit width
|
||||
*/
|
||||
public HDLNodeExpression(String elementName, ElementAttributes elementAttributes, HDLContext.BitProvider bitProvider) {
|
||||
super(elementName, elementAttributes, bitProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the expression tu use
|
||||
*
|
||||
* @param expression the expression
|
||||
*/
|
||||
public void setExpression(Expression expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expression
|
||||
*/
|
||||
public Expression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
getOutput().getNet().print(out);
|
||||
out.print(" := ");
|
||||
expression.print(out);
|
||||
out.println();
|
||||
}
|
||||
|
||||
}
|
@ -5,19 +5,44 @@
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2;
|
||||
|
||||
public class HDLPort {
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A port
|
||||
*/
|
||||
public class HDLPort implements Printable {
|
||||
|
||||
/**
|
||||
* The ports direction
|
||||
*/
|
||||
public enum Direction {
|
||||
IN, OUT
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
IN,
|
||||
/**
|
||||
* output
|
||||
*/
|
||||
OUT
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final Direction direction;
|
||||
private int bits;
|
||||
private HDLNet net;
|
||||
private HDLNode node;
|
||||
private String pinNumber;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param name the name of the port
|
||||
* @param net the net of this port
|
||||
* @param direction the ports direction
|
||||
* @param bits the bit width
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public HDLPort(String name, HDLNet net, Direction direction, int bits) throws HDLException {
|
||||
this.name = name;
|
||||
this.net = net;
|
||||
@ -28,42 +53,70 @@ public class HDLPort {
|
||||
net.addPort(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pin number to this port
|
||||
*
|
||||
* @param pinNumber the pin number
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public HDLPort setPinNumber(String pinNumber) {
|
||||
this.pinNumber = pinNumber;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the net of this port
|
||||
*/
|
||||
public HDLNet getNet() {
|
||||
return net;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the net of this port
|
||||
*
|
||||
* @param net the net
|
||||
* @throws HDLException HDLException
|
||||
*/
|
||||
public void setNet(HDLNet net) throws HDLException {
|
||||
this.net = net;
|
||||
net.addPort(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of this port
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bit width of this port
|
||||
*/
|
||||
public int getBits() {
|
||||
return bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bit width of this port
|
||||
*
|
||||
* @param bits the number of bits
|
||||
*/
|
||||
public void setBits(int bits) {
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ports direction
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public HDLNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(HDLNode node) {
|
||||
this.node = node;
|
||||
/**
|
||||
* @return the pin number of this port
|
||||
*/
|
||||
public String getPinNumber() {
|
||||
return pinNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,4 +124,8 @@ public class HDLPort {
|
||||
return direction + " " + name + "(" + bits + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print(name).print(":").print(bits);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,14 @@
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2;
|
||||
|
||||
/**
|
||||
* Visitor to visit the nodes.
|
||||
*/
|
||||
public interface HDLVisitor {
|
||||
/**
|
||||
* Visits a node
|
||||
*
|
||||
* @param hdlNode the node to visit
|
||||
*/
|
||||
void visit(HDLNode hdlNode);
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2;
|
||||
|
||||
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Helper to merge expressions
|
||||
*/
|
||||
class OperationMerger {
|
||||
private final ArrayList<HDLNode> nodes;
|
||||
private final HDLCircuit circuit;
|
||||
|
||||
OperationMerger(ArrayList<HDLNode> nodes, HDLCircuit circuit) {
|
||||
this.nodes = nodes;
|
||||
this.circuit = circuit;
|
||||
}
|
||||
|
||||
ArrayList<HDLNode> merge() throws HDLException {
|
||||
boolean wasOptimization;
|
||||
do {
|
||||
wasOptimization = false;
|
||||
outer:
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
HDLNode n1 = nodes.get(i);
|
||||
if (n1 instanceof HDLNodeExpression) {
|
||||
for (HDLPort p : n1.getInputs()) {
|
||||
HDLNode n2 = searchCreator(p.getNet());
|
||||
if (n2 != null && n2 instanceof HDLNodeExpression) {
|
||||
if (n2.getOutputs().size() == 1 && n2.getOutput().getNet().getInputs().size() == 1) {
|
||||
nodes.set(i, merge((HDLNodeExpression) n1, (HDLNodeExpression) n2));
|
||||
nodes.remove(n2);
|
||||
wasOptimization = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (wasOptimization);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private HDLNodeExpression merge(HDLNodeExpression host, HDLNodeExpression include) throws HDLException {
|
||||
final Expression expression = host.getExpression();
|
||||
expression.replace(include.getOutput().getNet(), include.getExpression());
|
||||
|
||||
HDLNodeExpression node = new HDLNodeExpression("merged expression",
|
||||
null, name -> host.getOutput().getBits());
|
||||
node.setExpression(expression);
|
||||
|
||||
circuit.removeNet(include.getOutput().getNet());
|
||||
|
||||
node.addOutput(host.getOutput());
|
||||
for (HDLPort i : host.getInputs())
|
||||
node.addInput(i);
|
||||
|
||||
for (HDLPort i : include.getInputs())
|
||||
if (!node.hasInput(i))
|
||||
node.addInput(i);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private HDLNode searchCreator(HDLNet net) {
|
||||
for (HDLNode n : nodes)
|
||||
for (HDLPort p : n.getOutputs())
|
||||
if (p.getNet() == net)
|
||||
return n;
|
||||
return null;
|
||||
}
|
||||
}
|
23
src/main/java/de/neemann/digital/hdl/model2/Printable.java
Normal file
23
src/main/java/de/neemann/digital/hdl/model2/Printable.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2;
|
||||
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Something which can print itself to a CodePrinter
|
||||
*/
|
||||
public interface Printable {
|
||||
/**
|
||||
* Prints itfels to the CodePrinter
|
||||
*
|
||||
* @param out the CodePrinter instance
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
void print(CodePrinter out) throws IOException;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2.expression;
|
||||
|
||||
import de.neemann.digital.hdl.model2.HDLNet;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents a constant
|
||||
*/
|
||||
public class ExprConstant implements Expression {
|
||||
|
||||
private long value;
|
||||
private int bits;
|
||||
|
||||
/**
|
||||
* Creates a new constant
|
||||
* @param value the value
|
||||
* @param bits the number of bits
|
||||
*/
|
||||
public ExprConstant(long value, int bits) {
|
||||
this.value = value;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of bits
|
||||
*/
|
||||
public int getBits() {
|
||||
return bits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print(value).print(":").print(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(HDLNet net, Expression expression) {
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2.expression;
|
||||
|
||||
|
||||
import de.neemann.digital.hdl.model2.HDLNet;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents a NOT operation
|
||||
*/
|
||||
public class ExprNot implements Expression {
|
||||
|
||||
private Expression expr;
|
||||
|
||||
/**
|
||||
* Creates a new NOT expression
|
||||
*
|
||||
* @param expr the enxpression to invert
|
||||
*/
|
||||
public ExprNot(Expression expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expression
|
||||
*/
|
||||
public Expression getExpression() {
|
||||
return expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print("NOT ");
|
||||
expr.print(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(HDLNet net, Expression expression) {
|
||||
if (isVar(expr, net))
|
||||
expr = expression;
|
||||
else
|
||||
expr.replace(net, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Help er to check if a expression is a net reference
|
||||
*
|
||||
* @param expr the expression to check
|
||||
* @param net the net
|
||||
* @return true if the expression is a reference to the given net
|
||||
*/
|
||||
public static boolean isVar(Expression expr, HDLNet net) {
|
||||
return expr instanceof ExprVar && ((ExprVar) expr).getNet() == net;
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2.expression;
|
||||
|
||||
|
||||
import de.neemann.digital.hdl.model2.HDLNet;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static de.neemann.digital.hdl.model2.expression.ExprNot.isVar;
|
||||
|
||||
/**
|
||||
* Represenst a operation
|
||||
*/
|
||||
public class ExprOperate implements Expression {
|
||||
/**
|
||||
* the possible operation
|
||||
*/
|
||||
public enum Operation {
|
||||
/**
|
||||
* And operation
|
||||
*/
|
||||
AND,
|
||||
/**
|
||||
* Or operation
|
||||
*/
|
||||
OR,
|
||||
/**
|
||||
* xor operation
|
||||
*/
|
||||
XOR
|
||||
}
|
||||
|
||||
private Operation operation;
|
||||
private ArrayList<Expression> operands;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param operation the operation
|
||||
* @param operands the operandes
|
||||
*/
|
||||
public ExprOperate(Operation operation, ArrayList<Expression> operands) {
|
||||
this.operation = operation;
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the operation
|
||||
*/
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the operands
|
||||
*/
|
||||
public ArrayList<Expression> getOperands() {
|
||||
return operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
out.print("(");
|
||||
boolean first = true;
|
||||
for (Expression op : operands) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out.print(" ").print(operation.name()).print(" ");
|
||||
op.print(out);
|
||||
}
|
||||
out.print(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(HDLNet net, Expression expression) {
|
||||
for (int i = 0; i < operands.size(); i++) {
|
||||
final Expression op = operands.get(i);
|
||||
if (isVar(op, net))
|
||||
operands.set(i, expression);
|
||||
else
|
||||
op.replace(net, expression);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2.expression;
|
||||
|
||||
import de.neemann.digital.hdl.model2.HDLNet;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A reference to a net
|
||||
*/
|
||||
public class ExprVar implements Expression {
|
||||
private HDLNet net;
|
||||
|
||||
/**
|
||||
* creates a new net reference
|
||||
*
|
||||
* @param net the net
|
||||
*/
|
||||
public ExprVar(HDLNet net) {
|
||||
this.net = net;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the net
|
||||
*/
|
||||
public HDLNet getNet() {
|
||||
return net;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(CodePrinter out) throws IOException {
|
||||
net.print(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replace(HDLNet net, Expression expression) {
|
||||
if (net == this.net)
|
||||
throw new RuntimeException("should not happen!");
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.hdl.model2.expression;
|
||||
|
||||
import de.neemann.digital.hdl.model2.HDLNet;
|
||||
import de.neemann.digital.hdl.model2.Printable;
|
||||
|
||||
/**
|
||||
* Represents a expression
|
||||
*/
|
||||
public interface Expression extends Printable {
|
||||
|
||||
/**
|
||||
* Replaces a net with and expression
|
||||
*
|
||||
* @param net the net to replace
|
||||
* @param expression the expression to use instead ot the net
|
||||
*/
|
||||
void replace(HDLNet net, Expression expression);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes to describe a model expression
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2.expression;
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The hdl representation of a circuit
|
||||
*/
|
||||
package de.neemann.digital.hdl.model2;
|
@ -5,6 +5,8 @@ import de.neemann.digital.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||
import de.neemann.digital.hdl.printer.CodePrinterStr;
|
||||
import de.neemann.digital.integration.Resources;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -14,7 +16,7 @@ import java.io.IOException;
|
||||
public class HDLCircuitTest extends TestCase {
|
||||
|
||||
public void testSimple() throws IOException, PinException, HDLException, NodeException {
|
||||
File file = new File(Resources.getRoot(), "../../main/dig/processor/VHDLExample.dig");
|
||||
File file = new File(Resources.getRoot(), "dig/hdl/model2/comb.dig");
|
||||
ElementLibrary library = new ElementLibrary();
|
||||
library.setRootFilePath(file.getParentFile());
|
||||
ShapeFactory shapeFactory = new ShapeFactory(library);
|
||||
@ -23,8 +25,25 @@ public class HDLCircuitTest extends TestCase {
|
||||
final HDLContext hdlContext = new HDLContext(library);
|
||||
HDLCircuit hdl = new HDLCircuit(c, "main", hdlContext);
|
||||
|
||||
System.out.println(hdl);
|
||||
hdl.traverse(System.out::println);
|
||||
CodePrinterStr out = new CodePrinterStr();
|
||||
for (HDLCircuit cir : hdlContext) {
|
||||
cir.mergeOperations();
|
||||
cir.print(out);
|
||||
out.println();
|
||||
}
|
||||
|
||||
hdl.mergeOperations().nameNets(new HDLCircuit.NetNamer() {
|
||||
private int num;
|
||||
|
||||
@Override
|
||||
public String createName(HDLNet n) {
|
||||
return "s" + (num++);
|
||||
}
|
||||
});
|
||||
hdl.print(out);
|
||||
|
||||
System.out.print(out);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
352
src/test/resources/dig/hdl/model2/comb.dig
Normal file
352
src/test/resources/dig/hdl/model2/comb.dig
Normal file
@ -0,0 +1,352 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<attributes/>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>X</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>1</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>And</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Inputs</string>
|
||||
<int>5</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="160" y="100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Or</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="20" y="0"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Or</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="20" y="80"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Or</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="20" y="240"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>A</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-120" y="-100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-100" y="-60"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>B</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-80" y="-100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>C</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-40" y="-100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Not</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>rotation</string>
|
||||
<rotation rotation="3"/>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="-20" y="-60"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>NOr</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="20" y="160"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Y</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="260"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Z</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="300"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Const</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="140" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>D_FF</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="280" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Const</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="260" y="160"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>Aident</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="360" y="340"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="-120" y="0"/>
|
||||
<p2 x="20" y="0"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-80" y="160"/>
|
||||
<p2 x="20" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="120" y="160"/>
|
||||
<p2 x="160" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="260" y="160"/>
|
||||
<p2 x="280" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="100"/>
|
||||
<p2 x="160" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="80" y="100"/>
|
||||
<p2 x="120" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="80" y="260"/>
|
||||
<p2 x="140" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="260"/>
|
||||
<p2 x="360" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="40"/>
|
||||
<p2 x="20" y="40"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="200"/>
|
||||
<p2 x="20" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="140"/>
|
||||
<p2 x="280" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="140"/>
|
||||
<p2 x="160" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="140"/>
|
||||
<p2 x="360" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="300"/>
|
||||
<p2 x="360" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="-80"/>
|
||||
<p2 x="-100" y="-80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="-80"/>
|
||||
<p2 x="-20" y="-80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="80"/>
|
||||
<p2 x="20" y="80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-80" y="240"/>
|
||||
<p2 x="20" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="80" y="20"/>
|
||||
<p2 x="140" y="20"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="100" y="180"/>
|
||||
<p2 x="120" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="180"/>
|
||||
<p2 x="160" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="340"/>
|
||||
<p2 x="360" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="120"/>
|
||||
<p2 x="20" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="120" y="120"/>
|
||||
<p2 x="160" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-20" y="280"/>
|
||||
<p2 x="20" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="-80"/>
|
||||
<p2 x="-100" y="-60"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="-20"/>
|
||||
<p2 x="-100" y="80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="80"/>
|
||||
<p2 x="-100" y="300"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-100" y="300"/>
|
||||
<p2 x="-100" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-20" y="-80"/>
|
||||
<p2 x="-20" y="-60"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-20" y="-20"/>
|
||||
<p2 x="-20" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-20" y="280"/>
|
||||
<p2 x="-20" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="-100"/>
|
||||
<p2 x="-120" y="-80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="0"/>
|
||||
<p2 x="-120" y="340"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="340"/>
|
||||
<p2 x="-120" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-120" y="-80"/>
|
||||
<p2 x="-120" y="0"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="-100"/>
|
||||
<p2 x="-40" y="-80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="200"/>
|
||||
<p2 x="-40" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="-80"/>
|
||||
<p2 x="-40" y="40"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="40"/>
|
||||
<p2 x="-40" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-40" y="120"/>
|
||||
<p2 x="-40" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="120" y="100"/>
|
||||
<p2 x="120" y="120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="120" y="160"/>
|
||||
<p2 x="120" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="20"/>
|
||||
<p2 x="140" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="140" y="180"/>
|
||||
<p2 x="140" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-80" y="-100"/>
|
||||
<p2 x="-80" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-80" y="160"/>
|
||||
<p2 x="-80" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="-80" y="240"/>
|
||||
<p2 x="-80" y="360"/>
|
||||
</wire>
|
||||
</wires>
|
||||
</circuit>
|
Loading…
x
Reference in New Issue
Block a user