mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -04:00
More clear handling of entity input expressions.
Moves a bit more more logic to the model.
This commit is contained in:
parent
ded20a5462
commit
6cc350e488
@ -28,6 +28,7 @@ import de.neemann.digital.hdl.model2.clock.ClockInfo;
|
|||||||
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
||||||
import de.neemann.digital.hdl.model2.expression.ExprNot;
|
import de.neemann.digital.hdl.model2.expression.ExprNot;
|
||||||
import de.neemann.digital.hdl.model2.expression.ExprVar;
|
import de.neemann.digital.hdl.model2.expression.ExprVar;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||||
import de.neemann.digital.hdl.model2.optimizations.*;
|
import de.neemann.digital.hdl.model2.optimizations.*;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
@ -486,6 +487,8 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
.addPort(new HDLPort("cout", outNet, HDLPort.Direction.OUT, 1))
|
.addPort(new HDLPort("cout", outNet, HDLPort.Direction.OUT, 1))
|
||||||
.addPort(new HDLPort("cin", inNet, HDLPort.Direction.IN, 1));
|
.addPort(new HDLPort("cin", inNet, HDLPort.Direction.IN, 1));
|
||||||
|
|
||||||
|
clockNode.createExpressions();
|
||||||
|
|
||||||
nodes.add(clockNode);
|
nodes.add(clockNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,6 +527,17 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
return nameUnnamedSignals();
|
return nameUnnamedSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to replace a net by an expression
|
||||||
|
*
|
||||||
|
* @param net the net to replace
|
||||||
|
* @param expression the expression to use instead
|
||||||
|
*/
|
||||||
|
public void replaceNetByExpression(HDLNet net, Expression expression) {
|
||||||
|
for (HDLNode n : nodes)
|
||||||
|
n.replaceNetByExpression(net, expression);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The net naming algorithm
|
* The net naming algorithm
|
||||||
*/
|
*/
|
||||||
|
@ -69,7 +69,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
|
|
||||||
return addInputsOutputs(
|
return addInputsOutputs(
|
||||||
new HDLNodeCustom(v.getElementName(), v.getElementAttributes(), c),
|
new HDLNodeCustom(v.getElementName(), v.getElementAttributes(), c),
|
||||||
v, parent);
|
v, parent).createExpressions();
|
||||||
|
|
||||||
} else if (v.equalsDescription(Const.DESCRIPTION)) {
|
} else if (v.equalsDescription(Const.DESCRIPTION)) {
|
||||||
final HDLNodeAssignment node = createExpression(v, parent, td);
|
final HDLNodeAssignment node = createExpression(v, parent, td);
|
||||||
@ -117,7 +117,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
v.getElementAttributes(),
|
v.getElementAttributes(),
|
||||||
new ObservableValuesBitsProvider(
|
new ObservableValuesBitsProvider(
|
||||||
td.createElement(v.getElementAttributes()).getOutputs())),
|
td.createElement(v.getElementAttributes()).getOutputs())),
|
||||||
v, parent);
|
v, parent).createExpressions();
|
||||||
|
|
||||||
|
|
||||||
} catch (ElementNotFoundException | PinException | NodeException e) {
|
} catch (ElementNotFoundException | PinException | NodeException e) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
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.model2.expression.Expression;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -14,7 +15,7 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* The base class of all nodes
|
* The base class of all nodes
|
||||||
*/
|
*/
|
||||||
public class HDLNode {
|
public abstract class HDLNode {
|
||||||
private final String elementName;
|
private final String elementName;
|
||||||
private final ElementAttributes elementAttributes;
|
private final ElementAttributes elementAttributes;
|
||||||
private final HDLModel.BitProvider bitProvider;
|
private final HDLModel.BitProvider bitProvider;
|
||||||
@ -165,16 +166,6 @@ public class HDLNode {
|
|||||||
return hdlEntityName;
|
return hdlEntityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks is inlining is possible
|
|
||||||
*
|
|
||||||
* @param net the net which should be inlined
|
|
||||||
* @return true if inlining of the given net is possible
|
|
||||||
*/
|
|
||||||
public boolean inliningPossible(HDLNet net) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames the signals in this node.
|
* Renames the signals in this node.
|
||||||
*
|
*
|
||||||
@ -186,4 +177,12 @@ public class HDLNode {
|
|||||||
for (HDLPort p : inputs)
|
for (HDLPort p : inputs)
|
||||||
p.rename(renaming);
|
p.rename(renaming);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to replace a net by an expression.
|
||||||
|
*
|
||||||
|
* @param net the net to replace
|
||||||
|
* @param expression the expression to use instead
|
||||||
|
*/
|
||||||
|
public abstract void replaceNetByExpression(HDLNet net, Expression expression);
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,11 @@ public class HDLNodeAssignment extends HDLNode {
|
|||||||
expression.replace(oldNet, new ExprVar(newNet));
|
expression.replace(oldNet, new ExprVar(newNet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceNetByExpression(HDLNet net, Expression expression) {
|
||||||
|
expression.replace(net, expression);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the target net of this expression.
|
* @return the target net of this expression.
|
||||||
*/
|
*/
|
||||||
|
@ -6,11 +6,18 @@
|
|||||||
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.model2.expression.ExprVar;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node which represents a build-in component
|
* A node which represents a build-in component
|
||||||
*/
|
*/
|
||||||
public class HDLNodeBuildIn extends HDLNode {
|
public class HDLNodeBuildIn extends HDLNode implements Iterable<HDLNodeBuildIn.InputAssignment> {
|
||||||
|
private ArrayList<InputAssignment> inputAssignement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates e new instance
|
* Creates e new instance
|
||||||
*
|
*
|
||||||
@ -20,5 +27,73 @@ public class HDLNodeBuildIn extends HDLNode {
|
|||||||
*/
|
*/
|
||||||
public HDLNodeBuildIn(String elementName, ElementAttributes elementAttributes, HDLModel.BitProvider bitProvider) {
|
public HDLNodeBuildIn(String elementName, ElementAttributes elementAttributes, HDLModel.BitProvider bitProvider) {
|
||||||
super(elementName, elementAttributes, bitProvider);
|
super(elementName, elementAttributes, bitProvider);
|
||||||
|
inputAssignement = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceNetByExpression(HDLNet net, Expression expression) {
|
||||||
|
for (InputAssignment ia : inputAssignement)
|
||||||
|
ia.replaceNetByExpression(net, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
HDLNode createExpressions() {
|
||||||
|
for (HDLPort in : getInputs())
|
||||||
|
inputAssignement.add(new InputAssignment(in.getName(), new ExprVar(in.getNet())));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<InputAssignment> iterator() {
|
||||||
|
if (getInputs().size() != inputAssignement.size())
|
||||||
|
throw new RuntimeException("no expressions created for " + getElementName());
|
||||||
|
|
||||||
|
return inputAssignement.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rename(HDLModel.Renaming renaming) {
|
||||||
|
super.rename(renaming);
|
||||||
|
for (InputAssignment in : inputAssignement)
|
||||||
|
in.rename(renaming);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A port assignment.
|
||||||
|
* Connects a port to an expression
|
||||||
|
*/
|
||||||
|
public static final class InputAssignment {
|
||||||
|
private String name;
|
||||||
|
private Expression expression;
|
||||||
|
|
||||||
|
private InputAssignment(String name, Expression expression) {
|
||||||
|
this.name = name;
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the targtet signal name
|
||||||
|
*/
|
||||||
|
public String getTargetName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the expression to assign
|
||||||
|
*/
|
||||||
|
public Expression getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceNetByExpression(HDLNet net, Expression expr) {
|
||||||
|
if (Expression.isVar(expression, net))
|
||||||
|
expression = expr;
|
||||||
|
else
|
||||||
|
expr.replace(net, expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rename(HDLModel.Renaming renaming) {
|
||||||
|
name = renaming.checkName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import de.neemann.digital.core.element.ElementAttributes;
|
|||||||
/**
|
/**
|
||||||
* Represents a node which is build from a circuit.
|
* Represents a node which is build from a circuit.
|
||||||
*/
|
*/
|
||||||
public class HDLNodeCustom extends HDLNode {
|
public class HDLNodeCustom extends HDLNodeBuildIn {
|
||||||
private final HDLCircuit hdlCircuit;
|
private final HDLCircuit hdlCircuit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,16 +6,20 @@
|
|||||||
package de.neemann.digital.hdl.model2;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
import de.neemann.digital.core.wiring.Splitter;
|
import de.neemann.digital.core.wiring.Splitter;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.ExprVar;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Many to One splitter.
|
* The Many to One splitter.
|
||||||
* A Many to Many splitter is build with a ManyToOne and a OneToMany splitter.
|
* A Many to Many splitter is build with a ManyToOne and a OneToMany splitter.
|
||||||
*/
|
*/
|
||||||
public class HDLNodeSplitterManyToOne extends HDLNode {
|
public class HDLNodeSplitterManyToOne extends HDLNode implements Iterable<HDLNodeSplitterManyToOne.SplitterAssignment> {
|
||||||
private final Splitter.Ports inputSplit;
|
private final ArrayList<SplitterAssignment> outputs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -25,20 +29,23 @@ public class HDLNodeSplitterManyToOne extends HDLNode {
|
|||||||
*/
|
*/
|
||||||
HDLNodeSplitterManyToOne(HDLNode node, Splitter.Ports inputSplit) {
|
HDLNodeSplitterManyToOne(HDLNode node, Splitter.Ports inputSplit) {
|
||||||
super(node.getElementName(), node.getElementAttributes(), null);
|
super(node.getElementName(), node.getElementAttributes(), null);
|
||||||
this.inputSplit = inputSplit;
|
|
||||||
|
outputs = new ArrayList<>();
|
||||||
|
int i = 0;
|
||||||
|
for (Splitter.Port p : inputSplit) {
|
||||||
|
outputs.add(new SplitterAssignment(
|
||||||
|
p.getPos() + p.getBits() - 1,
|
||||||
|
p.getPos(),
|
||||||
|
new ExprVar(node.getInputs().get(i).getNet())));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
for (HDLPort p : node.getInputs())
|
for (HDLPort p : node.getInputs())
|
||||||
addPort(p);
|
addPort(p);
|
||||||
for (HDLPort p : node.getOutputs())
|
for (HDLPort p : node.getOutputs())
|
||||||
addPort(p);
|
addPort(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the input splitting
|
|
||||||
*/
|
|
||||||
public Splitter.Ports getInputSplit() {
|
|
||||||
return inputSplit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the targets signal name
|
* @return the targets signal name
|
||||||
*/
|
*/
|
||||||
@ -51,13 +58,70 @@ public class HDLNodeSplitterManyToOne extends HDLNode {
|
|||||||
super.print(out);
|
super.print(out);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
HDLPort o = getOutput();
|
HDLPort o = getOutput();
|
||||||
for (Splitter.Port sp : inputSplit) {
|
for (SplitterAssignment sp : this) {
|
||||||
HDLPort p = getInputs().get(i++);
|
out.print(o.getNet().getName());
|
||||||
out.print(o.getNet().getName())
|
outputs.get(i++).print(out);
|
||||||
.print("(").print(sp.getPos()).print("-").print(sp.getPos() + sp.getBits() - 1).print(")")
|
out.println();
|
||||||
.print(" := ").println(p.getNet().getName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceNetByExpression(HDLNet net, Expression expression) {
|
||||||
|
for (SplitterAssignment p : this)
|
||||||
|
p.replace(net, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<SplitterAssignment> iterator() {
|
||||||
|
return outputs.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The splitter assignment
|
||||||
|
*/
|
||||||
|
public final static class SplitterAssignment implements Printable {
|
||||||
|
private final int msb;
|
||||||
|
private final int lsb;
|
||||||
|
private Expression expression;
|
||||||
|
|
||||||
|
private SplitterAssignment(int msb, int lsb, Expression expression) {
|
||||||
|
this.msb = msb;
|
||||||
|
this.lsb = lsb;
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void print(CodePrinter out) throws IOException {
|
||||||
|
out.print("(").print(msb).print("-").print(lsb).print(")").print(" := ");
|
||||||
|
expression.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the msb of the assignment
|
||||||
|
*/
|
||||||
|
public int getMsb() {
|
||||||
|
return msb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lsb of the assignment
|
||||||
|
*/
|
||||||
|
public int getLsb() {
|
||||||
|
return lsb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the expression to assign
|
||||||
|
*/
|
||||||
|
public Expression getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replace(HDLNet net, Expression expr) {
|
||||||
|
if (Expression.isVar(expression, net))
|
||||||
|
expression = expr;
|
||||||
|
else
|
||||||
|
expression.replace(net, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package de.neemann.digital.hdl.model2;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
import de.neemann.digital.core.wiring.Splitter;
|
import de.neemann.digital.core.wiring.Splitter;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.Expression;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -51,6 +52,10 @@ public class HDLNodeSplitterOneToMany extends HDLNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceNetByExpression(HDLNet net, Expression expression) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the source signals name
|
* @return the source signals name
|
||||||
*/
|
*/
|
||||||
|
@ -21,6 +21,15 @@ public class ExprConstant implements Expression {
|
|||||||
private long value;
|
private long value;
|
||||||
private int bits;
|
private int bits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new constant
|
||||||
|
*
|
||||||
|
* @param constant the constant
|
||||||
|
*/
|
||||||
|
public ExprConstant(ExprConstant constant) {
|
||||||
|
this(constant.getValue(), constant.getBits());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new constant
|
* Creates a new constant
|
||||||
*
|
*
|
||||||
|
@ -42,20 +42,10 @@ public class ExprNot implements Expression {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replace(HDLNet net, Expression expression) {
|
public void replace(HDLNet net, Expression expression) {
|
||||||
if (isVar(expr, net))
|
if (Expression.isVar(expr, net))
|
||||||
expr = expression;
|
expr = expression;
|
||||||
else
|
else
|
||||||
expr.replace(net, expression);
|
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
|
|
||||||
*/
|
|
||||||
static boolean isVar(Expression expr, HDLNet net) {
|
|
||||||
return expr instanceof ExprVar && ((ExprVar) expr).getNet() == net;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@ import de.neemann.digital.hdl.printer.CodePrinter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import static de.neemann.digital.hdl.model2.expression.ExprNot.isVar;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represenst a operation
|
* Represenst a operation
|
||||||
*/
|
*/
|
||||||
@ -82,7 +80,7 @@ public class ExprOperate implements Expression {
|
|||||||
public void replace(HDLNet net, Expression expression) {
|
public void replace(HDLNet net, Expression expression) {
|
||||||
for (int i = 0; i < operands.size(); i++) {
|
for (int i = 0; i < operands.size(); i++) {
|
||||||
final Expression op = operands.get(i);
|
final Expression op = operands.get(i);
|
||||||
if (isVar(op, net))
|
if (Expression.isVar(op, net))
|
||||||
operands.set(i, expression);
|
operands.set(i, expression);
|
||||||
else
|
else
|
||||||
op.replace(net, expression);
|
op.replace(net, expression);
|
||||||
|
@ -22,6 +22,8 @@ public class ExprVar implements Expression {
|
|||||||
* @param net the net
|
* @param net the net
|
||||||
*/
|
*/
|
||||||
public ExprVar(HDLNet net) {
|
public ExprVar(HDLNet net) {
|
||||||
|
if (net == null)
|
||||||
|
throw new NullPointerException("net is null");
|
||||||
this.net = net;
|
this.net = net;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,4 +21,15 @@ public interface Expression extends Printable {
|
|||||||
*/
|
*/
|
||||||
void replace(HDLNet net, Expression expression);
|
void replace(HDLNet net, Expression 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
|
||||||
|
*/
|
||||||
|
static boolean isVar(Expression expr, HDLNet net) {
|
||||||
|
return expr instanceof ExprVar && ((ExprVar) expr).getNet() == net;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package de.neemann.digital.hdl.model2.optimizations;
|
package de.neemann.digital.hdl.model2.optimizations;
|
||||||
|
|
||||||
import de.neemann.digital.hdl.model2.*;
|
import de.neemann.digital.hdl.model2.*;
|
||||||
|
import de.neemann.digital.hdl.model2.expression.ExprConstant;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@ -21,10 +22,11 @@ public class RemoveConstantSignals implements Optimization {
|
|||||||
Iterator<HDLNet> it = circuit.getNets().iterator();
|
Iterator<HDLNet> it = circuit.getNets().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
HDLNet net = it.next();
|
HDLNet net = it.next();
|
||||||
if (net.isConstant() != null && isOnlyUsedInSupportedNodes(net)) {
|
final ExprConstant constant = net.isConstant();
|
||||||
|
if (constant != null && isOnlyUsedInSupportedNodes(net)) {
|
||||||
circuit.getNodes().remove(net.getOutput().getParent());
|
circuit.getNodes().remove(net.getOutput().getParent());
|
||||||
it.remove();
|
it.remove();
|
||||||
// keep net in ports to allow the nodes to access the constant for inlining.
|
circuit.replaceNetByExpression(net, new ExprConstant(constant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import de.neemann.digital.hdl.model2.*;
|
|||||||
import de.neemann.digital.hdl.model2.expression.*;
|
import de.neemann.digital.hdl.model2.expression.*;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
import de.neemann.digital.hdl.vhdl2.entities.VHDLEntity;
|
import de.neemann.digital.hdl.vhdl2.entities.VHDLEntity;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -20,6 +22,7 @@ import java.util.HashSet;
|
|||||||
* Create the vhdl output
|
* Create the vhdl output
|
||||||
*/
|
*/
|
||||||
public class VHDLCreator {
|
public class VHDLCreator {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(VHDLCreator.class);
|
||||||
private static final String ZEROS = "0000000000000000000000000000000000000000000000000000000000000000";
|
private static final String ZEROS = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||||
private final CodePrinter out;
|
private final CodePrinter out;
|
||||||
private final VHDLLibrary library;
|
private final VHDLLibrary library;
|
||||||
@ -105,13 +108,14 @@ public class VHDLCreator {
|
|||||||
public void printHDLCircuit(HDLCircuit circuit) throws IOException, HDLException, HGSEvalException {
|
public void printHDLCircuit(HDLCircuit circuit) throws IOException, HDLException, HGSEvalException {
|
||||||
// at first print all used entities to maintain the correct order
|
// at first print all used entities to maintain the correct order
|
||||||
for (HDLNode node : circuit)
|
for (HDLNode node : circuit)
|
||||||
if (node instanceof HDLNodeBuildIn)
|
if (node instanceof HDLNodeCustom)
|
||||||
printNodeBuiltIn((HDLNodeBuildIn) node);
|
|
||||||
else if (node instanceof HDLNodeCustom)
|
|
||||||
printNodeCustom((HDLNodeCustom) node);
|
printNodeCustom((HDLNodeCustom) node);
|
||||||
|
else if (node instanceof HDLNodeBuildIn)
|
||||||
|
printNodeBuiltIn((HDLNodeBuildIn) node);
|
||||||
|
|
||||||
|
LOGGER.info("export " + circuit.getElementName());
|
||||||
|
|
||||||
// after that print this entity
|
// after that print this entity
|
||||||
|
|
||||||
out.println()
|
out.println()
|
||||||
.println("LIBRARY ieee;")
|
.println("LIBRARY ieee;")
|
||||||
.println("USE ieee.std_logic_1164.all;")
|
.println("USE ieee.std_logic_1164.all;")
|
||||||
@ -139,10 +143,10 @@ public class VHDLCreator {
|
|||||||
for (HDLNode node : circuit)
|
for (HDLNode node : circuit)
|
||||||
if (node instanceof HDLNodeAssignment)
|
if (node instanceof HDLNodeAssignment)
|
||||||
printExpression((HDLNodeAssignment) node);
|
printExpression((HDLNodeAssignment) node);
|
||||||
else if (node instanceof HDLNodeBuildIn || node instanceof HDLNodeCustom)
|
else if (node instanceof HDLNodeBuildIn)
|
||||||
printEntityInstantiation(node, num++);
|
printEntityInstantiation((HDLNodeBuildIn) node, num++);
|
||||||
// else if (node instanceof HDLNodeSplitterOneToMany)
|
else if (node instanceof HDLNodeSplitterOneToMany)
|
||||||
// printOneToMany((HDLNodeSplitterOneToMany) node);
|
printOneToMany((HDLNodeSplitterOneToMany) node);
|
||||||
else if (node instanceof HDLNodeSplitterManyToOne)
|
else if (node instanceof HDLNodeSplitterManyToOne)
|
||||||
printManyToOne((HDLNodeSplitterManyToOne) node);
|
printManyToOne((HDLNodeSplitterManyToOne) node);
|
||||||
else
|
else
|
||||||
@ -183,51 +187,42 @@ public class VHDLCreator {
|
|||||||
out.println(");").dec();
|
out.println(");").dec();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printManyToOne(HDLNodeSplitterManyToOne node) throws IOException {
|
private void printManyToOne(HDLNodeSplitterManyToOne node) throws IOException, HDLException {
|
||||||
String target = node.getTargetSignal();
|
String target = node.getTargetSignal();
|
||||||
Splitter.Ports is = node.getInputSplit();
|
|
||||||
int i = 0;
|
for (HDLNodeSplitterManyToOne.SplitterAssignment in : node) {
|
||||||
for (HDLPort in : node.getInputs()) {
|
|
||||||
Splitter.Port sp = is.getPort(i++);
|
|
||||||
out.print(target).print("(");
|
out.print(target).print("(");
|
||||||
if (in.getBits() == 1)
|
if (in.getLsb() == in.getMsb())
|
||||||
out.print(sp.getPos());
|
out.print(in.getLsb());
|
||||||
else
|
else
|
||||||
out.print(sp.getPos() + sp.getBits() - 1).print(" downto ").print(sp.getPos());
|
out.print(in.getMsb()).print(" downto ").print(in.getLsb());
|
||||||
out.print(") <= ");
|
out.print(") <= ");
|
||||||
printInlineConstant(in);
|
printExpression(in.getExpression());
|
||||||
out.println(";");
|
out.println(";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printInlineConstant(HDLPort in) throws IOException {
|
/**
|
||||||
ExprConstant con = ExprConstant.isConstant(in.getNet().getOutput().getParent());
|
* After ReplaceOneToMany optimization there are no such nodes in the model!
|
||||||
if (con == null)
|
*/
|
||||||
out.print(in.getNet().getName());
|
private void printOneToMany(HDLNodeSplitterOneToMany node) throws IOException {
|
||||||
|
String source = node.getSourceSignal();
|
||||||
|
Splitter.Ports is = node.getOutputSplit();
|
||||||
|
int i = 0;
|
||||||
|
for (HDLPort outPort : node.getOutputs()) {
|
||||||
|
Splitter.Port sp = is.getPort(i++);
|
||||||
|
if (outPort.getNet() != null) {
|
||||||
|
out.print(outPort.getNet().getName()).print(" <= ").print(source).print("(");
|
||||||
|
if (outPort.getBits() == 1)
|
||||||
|
out.print(sp.getPos());
|
||||||
else
|
else
|
||||||
out.print(VHDLCreator.value(con));
|
out.print(sp.getPos() + sp.getBits() - 1).print(" downto ").print(sp.getPos());
|
||||||
|
out.println(");");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// After ReplaceOneToMany optimization there are no such nodes in the model.
|
private void printEntityInstantiation(HDLNodeBuildIn node, int num) throws IOException, HDLException {
|
||||||
//
|
|
||||||
// private void printOneToMany(HDLNodeSplitterOneToMany node) throws IOException {
|
|
||||||
// String source = node.getSourceSignal();
|
|
||||||
// Splitter.Ports is = node.getOutputSplit();
|
|
||||||
// int i = 0;
|
|
||||||
// for (HDLPort outPort : node.getOutputs()) {
|
|
||||||
// Splitter.Port sp = is.getPort(i++);
|
|
||||||
// if (outPort.getNet() != null) {
|
|
||||||
// out.print(outPort.getNet().getName()).print(" <= ").print(source).print("(");
|
|
||||||
// if (outPort.getBits() == 1)
|
|
||||||
// out.print(sp.getPos());
|
|
||||||
// else
|
|
||||||
// out.print(sp.getPos() + sp.getBits() - 1).print(" downto ").print(sp.getPos());
|
|
||||||
// out.println(");");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void printEntityInstantiation(HDLNode node, int num) throws IOException, HDLException {
|
|
||||||
String entityName = node.getHdlEntityName();
|
String entityName = node.getHdlEntityName();
|
||||||
|
|
||||||
out.print("gate").print(num).print(": entity work.").print(entityName);
|
out.print("gate").print(num).print(": entity work.").print(entityName);
|
||||||
@ -241,12 +236,10 @@ public class VHDLCreator {
|
|||||||
library.getEntity(node).writeGenericMap(out, node);
|
library.getEntity(node).writeGenericMap(out, node);
|
||||||
out.println("port map (").inc();
|
out.println("port map (").inc();
|
||||||
Separator sep = new Separator(out, ",\n");
|
Separator sep = new Separator(out, ",\n");
|
||||||
for (HDLPort i : node.getInputs()) {
|
for (HDLNodeBuildIn.InputAssignment i : node) {
|
||||||
if (i.getNet() == null)
|
|
||||||
throw new HDLException("A input port without a net: " + i.getName() + " in " + entityName);
|
|
||||||
sep.check();
|
sep.check();
|
||||||
out.print(i.getName()).print(" => ");
|
out.print(i.getTargetName()).print(" => ");
|
||||||
printInlineConstant(i);
|
printExpression(i.getExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HDLPort o : node.getOutputs())
|
for (HDLPort o : node.getOutputs())
|
||||||
|
@ -155,8 +155,8 @@ public class HDLModelTest extends TestCase {
|
|||||||
" node Splitter\n" +
|
" node Splitter\n" +
|
||||||
" in(0,1:2 reads (A->1), 2,3:2 reads (B->1))\n" +
|
" in(0,1:2 reads (A->1), 2,3:2 reads (B->1))\n" +
|
||||||
" out(single:4 defines (s0->2))\n" +
|
" out(single:4 defines (s0->2))\n" +
|
||||||
" s0(0-1) := A\n" +
|
" s0(1-0) := A\n" +
|
||||||
" s0(2-3) := B\n" +
|
" s0(3-2) := B\n" +
|
||||||
" node splitter\n" +
|
" node splitter\n" +
|
||||||
" in(in:4 reads (s0->2))\n" +
|
" in(in:4 reads (s0->2))\n" +
|
||||||
" out(0:1 defines (X->1))\n" +
|
" out(0:1 defines (X->1))\n" +
|
||||||
@ -314,8 +314,8 @@ public class HDLModelTest extends TestCase {
|
|||||||
" node Splitter\n" +
|
" node Splitter\n" +
|
||||||
" in(0,1:2 reads (s0->1), 2,3:2 reads (s1->1))\n" +
|
" in(0,1:2 reads (s0->1), 2,3:2 reads (s1->1))\n" +
|
||||||
" out(0-3:4 defines (S->1))\n" +
|
" out(0-3:4 defines (S->1))\n" +
|
||||||
" S(0-1) := s0\n" +
|
" S(1-0) := s0\n" +
|
||||||
" S(2-3) := s1\n" +
|
" S(3-2) := s1\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"end circuit main\n", cp.toString());
|
"end circuit main\n", cp.toString());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user