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 visualElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the set of labels attached to this net
|
||||||
|
*/
|
||||||
public HashSet<String> getLabels() {
|
public HashSet<String> getLabels() {
|
||||||
return labelSet;
|
return labelSet;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import de.neemann.digital.core.NodeException;
|
|||||||
import de.neemann.digital.core.basic.Not;
|
import de.neemann.digital.core.basic.Not;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.core.element.PinDescription;
|
|
||||||
import de.neemann.digital.core.io.In;
|
import de.neemann.digital.core.io.In;
|
||||||
import de.neemann.digital.core.io.Out;
|
import de.neemann.digital.core.io.Out;
|
||||||
import de.neemann.digital.core.io.PowerSupply;
|
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.Net;
|
||||||
import de.neemann.digital.draw.model.NetList;
|
import de.neemann.digital.draw.model.NetList;
|
||||||
import de.neemann.digital.gui.components.data.DummyElement;
|
import de.neemann.digital.gui.components.data.DummyElement;
|
||||||
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
import de.neemann.digital.testing.TestCaseElement;
|
import de.neemann.digital.testing.TestCaseElement;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
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 String elementName;
|
||||||
private final ArrayList<HDLPort> outputs;
|
private final ArrayList<HDLPort> outputs;
|
||||||
private final ArrayList<HDLPort> inputs;
|
private final ArrayList<HDLPort> inputs;
|
||||||
|
private final ArrayList<HDLNet> listOfNets;
|
||||||
private NetList netList;
|
private NetList netList;
|
||||||
private ArrayList<HDLNode> nodes;
|
private ArrayList<HDLNode> nodes;
|
||||||
private HashMap<Net, HDLNet> nets;
|
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 {
|
public HDLCircuit(Circuit circuit, String elementName, HDLContext c) throws PinException, HDLException, NodeException {
|
||||||
this.elementName = elementName;
|
this.elementName = elementName;
|
||||||
inputs = new ArrayList<>();
|
inputs = new ArrayList<>();
|
||||||
@ -64,7 +75,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
|||||||
v.getElementAttributes().getBits())
|
v.getElementAttributes().getBits())
|
||||||
.setPinNumber(v.getElementAttributes().get(Keys.PINNUMBER)));
|
.setPinNumber(v.getElementAttributes().get(Keys.PINNUMBER)));
|
||||||
else if (isRealElement(v))
|
else if (isRealElement(v))
|
||||||
addNode(v, c);
|
nodes.add(c.createNode(v, this));
|
||||||
}
|
}
|
||||||
} catch (HDLException e) {
|
} catch (HDLException e) {
|
||||||
throw new HDLException("error parsing " + circuit.getOrigin(), e);
|
throw new HDLException("error parsing " + circuit.getOrigin(), e);
|
||||||
@ -89,6 +100,19 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nodes.addAll(newNodes);
|
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 {
|
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);
|
&& !v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HDLNet getNetOfPin(Pin pin) {
|
HDLNet getNetOfPin(Pin pin) {
|
||||||
Net n = netList.getNetOfPos(pin.getPos());
|
Net n = netList.getNetOfPos(pin.getPos());
|
||||||
if (n == null)
|
if (n == null)
|
||||||
return null;
|
return null;
|
||||||
@ -139,19 +163,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
|||||||
if (labels.size() == 1)
|
if (labels.size() == 1)
|
||||||
return labels.iterator().next();
|
return labels.iterator().next();
|
||||||
else
|
else
|
||||||
return Integer.toString(netNumber++);
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,18 +179,32 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the elements name
|
||||||
|
*/
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return elementName;
|
return elementName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the circuits outputs
|
||||||
|
*/
|
||||||
public ArrayList<HDLPort> getOutputs() {
|
public ArrayList<HDLPort> getOutputs() {
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the circuits inputs
|
||||||
|
*/
|
||||||
public ArrayList<HDLPort> getInputs() {
|
public ArrayList<HDLPort> getInputs() {
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverses all the nodes
|
||||||
|
*
|
||||||
|
* @param visitor the visitor to use
|
||||||
|
*/
|
||||||
public void traverse(HDLVisitor visitor) {
|
public void traverse(HDLVisitor visitor) {
|
||||||
for (HDLNode n : nodes)
|
for (HDLNode n : nodes)
|
||||||
n.traverse(visitor);
|
n.traverse(visitor);
|
||||||
@ -188,4 +214,109 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLContext.BitProvider {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "HDLCircuit{elementName='" + elementName + "'}";
|
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.NodeException;
|
||||||
import de.neemann.digital.core.ObservableValues;
|
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.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.Circuit;
|
||||||
|
import de.neemann.digital.draw.elements.Pin;
|
||||||
import de.neemann.digital.draw.elements.PinException;
|
import de.neemann.digital.draw.elements.PinException;
|
||||||
import de.neemann.digital.draw.elements.VisualElement;
|
import de.neemann.digital.draw.elements.VisualElement;
|
||||||
import de.neemann.digital.draw.library.ElementLibrary;
|
import de.neemann.digital.draw.library.ElementLibrary;
|
||||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
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.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 ElementLibrary elementLibrary;
|
||||||
private HashMap<Circuit, HDLCircuit> circuitMap;
|
private HashMap<Circuit, HDLCircuit> circuitMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param elementLibrary the element library
|
||||||
|
*/
|
||||||
public HDLContext(ElementLibrary elementLibrary) {
|
public HDLContext(ElementLibrary elementLibrary) {
|
||||||
this.elementLibrary = elementLibrary;
|
this.elementLibrary = elementLibrary;
|
||||||
circuitMap = new HashMap<>();
|
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 {
|
try {
|
||||||
ElementTypeDescription td = elementLibrary.getElementType(v.getElementName());
|
ElementTypeDescription td = elementLibrary.getElementType(v.getElementName());
|
||||||
if (td instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
if (td instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||||
@ -38,26 +62,106 @@ public class HDLContext {
|
|||||||
circuitMap.put(tdc.getCircuit(), c);
|
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
|
} else
|
||||||
return new HDLNode(v.getElementName(),
|
return addInputsOutputs(
|
||||||
v.getElementAttributes(),
|
new HDLNode(v.getElementName(),
|
||||||
new ObserVableValuesBits(
|
v.getElementAttributes(),
|
||||||
td.createElement(v.getElementAttributes()).getOutputs()));
|
new ObservableValuesBitsProvider(
|
||||||
|
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||||
|
v, parent);
|
||||||
|
|
||||||
|
|
||||||
} catch (ElementNotFoundException | PinException | NodeException e) {
|
} catch (ElementNotFoundException | PinException | NodeException e) {
|
||||||
throw new HDLException("error creating node", 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 {
|
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);
|
int getBits(String name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ObserVableValuesBits implements BitProvider {
|
private static final class ObservableValuesBitsProvider implements BitProvider {
|
||||||
private final ObservableValues values;
|
private final ObservableValues values;
|
||||||
|
|
||||||
private ObserVableValuesBits(ObservableValues values) {
|
private ObservableValuesBitsProvider(ObservableValues values) {
|
||||||
this.values = values;
|
this.values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,11 +5,25 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.hdl.model2;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown during model building
|
||||||
|
*/
|
||||||
public class HDLException extends Exception {
|
public class HDLException extends Exception {
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param message the message
|
||||||
|
* @param cause the cause
|
||||||
|
*/
|
||||||
public HDLException(String message, Exception cause) {
|
public HDLException(String message, Exception cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param message the message
|
||||||
|
*/
|
||||||
public HDLException(String message) {
|
public HDLException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,38 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.hdl.model2;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
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 String name;
|
||||||
private ArrayList<HDLPort> inputs;
|
private ArrayList<HDLPort> inputs;
|
||||||
private HDLPort output;
|
private HDLPort output;
|
||||||
|
private boolean needsVariable = true;
|
||||||
|
private boolean isInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new net
|
||||||
|
*
|
||||||
|
* @param name the nets name
|
||||||
|
*/
|
||||||
public HDLNet(String name) {
|
public HDLNet(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
inputs = new ArrayList<>();
|
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 {
|
public void addPort(HDLPort hdlPort) throws HDLException {
|
||||||
if (hdlPort.getDirection().equals(HDLPort.Direction.OUT)) {
|
if (hdlPort.getDirection().equals(HDLPort.Direction.OUT)) {
|
||||||
if (output != null)
|
if (output != null)
|
||||||
@ -26,12 +46,26 @@ public class HDLNet {
|
|||||||
inputs.add(hdlPort);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name + " (" + output + " " + inputs + ")";
|
return name + " (" + output + " " + inputs + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixBits() throws HDLException {
|
void fixBits() throws HDLException {
|
||||||
if (output == null)
|
if (output == null)
|
||||||
throw new HDLException("no output connected to net");
|
throw new HDLException("no output connected to net");
|
||||||
final int bits = output.getBits();
|
final int bits = output.getBits();
|
||||||
@ -43,7 +77,56 @@ public class HDLNet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(HDLPort p) {
|
void remove(HDLPort p) {
|
||||||
inputs.remove(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;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A node which represents a built-in component
|
||||||
|
*/
|
||||||
public class HDLNode {
|
public class HDLNode {
|
||||||
private final String elementName;
|
private final String elementName;
|
||||||
private final ElementAttributes elementAttributes;
|
private final ElementAttributes elementAttributes;
|
||||||
@ -16,6 +21,13 @@ public class HDLNode {
|
|||||||
private final ArrayList<HDLPort> inputs;
|
private final ArrayList<HDLPort> inputs;
|
||||||
private final ArrayList<HDLPort> outputs;
|
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) {
|
public HDLNode(String elementName, ElementAttributes elementAttributes, HDLContext.BitProvider bitProvider) {
|
||||||
this.elementName = elementName;
|
this.elementName = elementName;
|
||||||
this.elementAttributes = elementAttributes;
|
this.elementAttributes = elementAttributes;
|
||||||
@ -24,14 +36,12 @@ public class HDLNode {
|
|||||||
outputs = new ArrayList<>();
|
outputs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInput(HDLPort port) {
|
void addInput(HDLPort port) {
|
||||||
inputs.add(port);
|
inputs.add(port);
|
||||||
port.setNode(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addOutput(HDLPort port) {
|
void addOutput(HDLPort port) {
|
||||||
outputs.add(port);
|
outputs.add(port);
|
||||||
port.setNode(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -39,27 +49,99 @@ public class HDLNode {
|
|||||||
return elementName + " " + inputs + " " + outputs;
|
return elementName + " " + inputs + " " + outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the elements name
|
||||||
|
*/
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return elementName;
|
return elementName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the elements attributes
|
||||||
|
*/
|
||||||
public ElementAttributes getElementAttributes() {
|
public ElementAttributes getElementAttributes() {
|
||||||
return elementAttributes;
|
return elementAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the nodes inputs
|
||||||
|
*/
|
||||||
public ArrayList<HDLPort> getInputs() {
|
public ArrayList<HDLPort> getInputs() {
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the nodes single outputs
|
||||||
|
*/
|
||||||
|
public HDLPort getOutput() {
|
||||||
|
return outputs.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the list of outputs
|
||||||
|
*/
|
||||||
public ArrayList<HDLPort> getOutputs() {
|
public ArrayList<HDLPort> getOutputs() {
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverses all the nodes
|
||||||
|
*
|
||||||
|
* @param visitor the visitor to use
|
||||||
|
*/
|
||||||
public void traverse(HDLVisitor visitor) {
|
public void traverse(HDLVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBits(String name) {
|
int getBits(String name) {
|
||||||
return bitProvider.getBits(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;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a node which is build from a circuit.
|
||||||
|
*/
|
||||||
public class HDLNodeCustom extends HDLNode {
|
public class HDLNodeCustom extends HDLNode {
|
||||||
private final HDLCircuit hdlCircuit;
|
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) {
|
public HDLNodeCustom(String elementName, ElementAttributes elementAttributes, HDLCircuit hdlCircuit) {
|
||||||
super(elementName, elementAttributes, hdlCircuit);
|
super(elementName, elementAttributes, hdlCircuit);
|
||||||
this.hdlCircuit = 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;
|
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 {
|
public enum Direction {
|
||||||
IN, OUT
|
/**
|
||||||
|
* input
|
||||||
|
*/
|
||||||
|
IN,
|
||||||
|
/**
|
||||||
|
* output
|
||||||
|
*/
|
||||||
|
OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Direction direction;
|
private final Direction direction;
|
||||||
private int bits;
|
private int bits;
|
||||||
private HDLNet net;
|
private HDLNet net;
|
||||||
private HDLNode node;
|
|
||||||
private String pinNumber;
|
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 {
|
public HDLPort(String name, HDLNet net, Direction direction, int bits) throws HDLException {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.net = net;
|
this.net = net;
|
||||||
@ -28,42 +53,70 @@ public class HDLPort {
|
|||||||
net.addPort(this);
|
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) {
|
public HDLPort setPinNumber(String pinNumber) {
|
||||||
this.pinNumber = pinNumber;
|
this.pinNumber = pinNumber;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the net of this port
|
||||||
|
*/
|
||||||
public HDLNet getNet() {
|
public HDLNet getNet() {
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the net of this port
|
||||||
|
*
|
||||||
|
* @param net the net
|
||||||
|
* @throws HDLException HDLException
|
||||||
|
*/
|
||||||
public void setNet(HDLNet net) throws HDLException {
|
public void setNet(HDLNet net) throws HDLException {
|
||||||
this.net = net;
|
this.net = net;
|
||||||
net.addPort(this);
|
net.addPort(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of this port
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the bit width of this port
|
||||||
|
*/
|
||||||
public int getBits() {
|
public int getBits() {
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the bit width of this port
|
||||||
|
*
|
||||||
|
* @param bits the number of bits
|
||||||
|
*/
|
||||||
public void setBits(int bits) {
|
public void setBits(int bits) {
|
||||||
this.bits = bits;
|
this.bits = bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ports direction
|
||||||
|
*/
|
||||||
public Direction getDirection() {
|
public Direction getDirection() {
|
||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HDLNode getNode() {
|
/**
|
||||||
return node;
|
* @return the pin number of this port
|
||||||
}
|
*/
|
||||||
|
public String getPinNumber() {
|
||||||
public void setNode(HDLNode node) {
|
return pinNumber;
|
||||||
this.node = node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,4 +124,8 @@ public class HDLPort {
|
|||||||
return direction + " " + name + "(" + bits + ")";
|
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;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visitor to visit the nodes.
|
||||||
|
*/
|
||||||
public interface HDLVisitor {
|
public interface HDLVisitor {
|
||||||
|
/**
|
||||||
|
* Visits a node
|
||||||
|
*
|
||||||
|
* @param hdlNode the node to visit
|
||||||
|
*/
|
||||||
void visit(HDLNode hdlNode);
|
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.elements.PinException;
|
||||||
import de.neemann.digital.draw.library.ElementLibrary;
|
import de.neemann.digital.draw.library.ElementLibrary;
|
||||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
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 de.neemann.digital.integration.Resources;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ import java.io.IOException;
|
|||||||
public class HDLCircuitTest extends TestCase {
|
public class HDLCircuitTest extends TestCase {
|
||||||
|
|
||||||
public void testSimple() throws IOException, PinException, HDLException, NodeException {
|
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();
|
ElementLibrary library = new ElementLibrary();
|
||||||
library.setRootFilePath(file.getParentFile());
|
library.setRootFilePath(file.getParentFile());
|
||||||
ShapeFactory shapeFactory = new ShapeFactory(library);
|
ShapeFactory shapeFactory = new ShapeFactory(library);
|
||||||
@ -23,8 +25,25 @@ public class HDLCircuitTest extends TestCase {
|
|||||||
final HDLContext hdlContext = new HDLContext(library);
|
final HDLContext hdlContext = new HDLContext(library);
|
||||||
HDLCircuit hdl = new HDLCircuit(c, "main", hdlContext);
|
HDLCircuit hdl = new HDLCircuit(c, "main", hdlContext);
|
||||||
|
|
||||||
System.out.println(hdl);
|
CodePrinterStr out = new CodePrinterStr();
|
||||||
hdl.traverse(System.out::println);
|
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