Merge branch 'master' into genModCirc

# Conflicts:
#	src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java
#	src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java
#	src/test/java/de/neemann/digital/integration/TestExamples.java
This commit is contained in:
hneemann 2021-01-07 19:48:37 +01:00
commit d69cea6d1d
10 changed files with 405 additions and 2 deletions

View File

@ -537,6 +537,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
public HDLCircuit applyDefaultOptimizations() throws HDLException {
apply(new ReplaceOneToMany());
apply(new MergeAssignments());
apply(new OptimizeExpressions(new ExprNot.OptimizeNotNot()));
apply(new InlineManyToOne());
apply(new RemoveConstantSignals());
apply(new MergeConstants()); // under certain circumstances there are still constants

View File

@ -9,6 +9,7 @@ package de.neemann.digital.hdl.model2;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.hdl.model2.expression.ExprVar;
import de.neemann.digital.hdl.model2.expression.Expression;
import de.neemann.digital.hdl.model2.expression.ExpressionOptimizer;
import de.neemann.digital.hdl.model2.expression.Visitor;
import de.neemann.digital.hdl.printer.CodePrinter;
@ -80,4 +81,12 @@ public class HDLNodeAssignment extends HDLNode {
return getOutput().getNet();
}
/**
* Optimizes the expression
*
* @param eo the optimizer
*/
public void optimize(ExpressionOptimizer eo) {
expression = eo.optimize(expression);
}
}

View File

@ -53,4 +53,25 @@ public class ExprNot implements Expression {
visitor.visit(this);
expr.traverse(visitor);
}
@Override
public void optimize(ExpressionOptimizer eo) {
expr = eo.optimize(expr);
expr.optimize(eo);
}
/**
* Optimizes not(not a) expressions to a
*/
public static class OptimizeNotNot implements ExpressionOptimizer {
@Override
public Expression optimize(Expression expression) {
if (expression instanceof ExprNot) {
ExprNot not = (ExprNot) expression;
if (not.expr instanceof ExprNot)
return optimize(((ExprNot) not.expr).expr);
}
return expression;
}
}
}

View File

@ -93,4 +93,13 @@ public class ExprOperate implements Expression {
for (Expression o : operands)
o.traverse(visitor);
}
@Override
public void optimize(ExpressionOptimizer eo) {
for (int i = 0; i < operands.size(); i++) {
Expression expr = eo.optimize(operands.get(i));
expr.optimize(eo);
operands.set(i, expr);
}
}
}

View File

@ -30,6 +30,15 @@ public interface Expression extends Printable {
visitor.visit(this);
}
/**
* Tries to optimize the expression by replacing it by a optimized one.
*
* @param eo the optimizer
*/
default void optimize(ExpressionOptimizer eo) {
}
/**
* Helper to check if an expression is a net reference
*

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2021 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;
/**
* Interface to optimize an expression
*/
public interface ExpressionOptimizer {
/**
* Optimizes the given expression.
* Should call itself on the returned expression if a optimization was made.
* See {@link ExprNot.OptimizeNotNot} as an example.
*
* @param expression the expression to optimize
* @return the optimizes expression or the given expression if optimization is not possible
*/
Expression optimize(Expression expression);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 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.optimizations;
import de.neemann.digital.hdl.model2.HDLCircuit;
import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.model2.HDLNode;
import de.neemann.digital.hdl.model2.HDLNodeAssignment;
import de.neemann.digital.hdl.model2.expression.ExpressionOptimizer;
/**
* Optimization which addresses the used expressions.
*/
public class OptimizeExpressions implements Optimization {
private final ExpressionOptimizer eo;
/**
* Creates a new instance
*
* @param eo the expression optimizer to use.
*/
public OptimizeExpressions(ExpressionOptimizer eo) {
this.eo = eo;
}
@Override
public void optimize(HDLCircuit circuit) throws HDLException {
for (HDLNode n : circuit.getNodes()) {
if (n instanceof HDLNodeAssignment) {
HDLNodeAssignment a = (HDLNodeAssignment) n;
a.optimize(eo);
}
}
}
}

View File

@ -300,7 +300,13 @@ public class VerilogCreator {
out.print(value(constant));
} else if (expression instanceof ExprNot) {
out.print("~ ");
printExpression(((ExprNot) expression).getExpression());
Expression inner = ((ExprNot) expression).getExpression();
if (inner instanceof ExprNot) { // Quartus does not like a NOT NOT
out.print("(");
printExpression(inner);
out.print(")");
} else
printExpression(inner);
} else if (expression instanceof ExprOperate) {
out.print("(");
boolean first = true;

View File

@ -290,7 +290,13 @@ public class VHDLCreator {
out.print(value(constant));
} else if (expression instanceof ExprNot) {
out.print("NOT ");
printExpression(((ExprNot) expression).getExpression());
Expression inner = ((ExprNot) expression).getExpression();
if (inner instanceof ExprNot) { // Quartus does not like a NOT NOT
out.print("(");
printExpression(inner);
out.print(")");
} else
printExpression(inner);
} else if (expression instanceof ExprOperate) {
out.print("(");
boolean first = true;

View File

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="340" y="180"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="360" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="340" y="220"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="360" y="220"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="420" y="220"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="340" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="360" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="420" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="480" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
</elementAttributes>
<pos x="340" y="300"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="360" y="300"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="420" y="300"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="480" y="300"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="540" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>E</string>
</entry>
</elementAttributes>
<pos x="340" y="340"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="360" y="340"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="420" y="340"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="480" y="340"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="540" y="340"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="600" y="340"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="660" y="340"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>X</string>
</entry>
</elementAttributes>
<pos x="660" y="300"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Z</string>
</entry>
</elementAttributes>
<pos x="660" y="260"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>U</string>
</entry>
</elementAttributes>
<pos x="660" y="220"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>V</string>
</entry>
</elementAttributes>
<pos x="660" y="180"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A B C D E Y X Z U V
0 0 0 0 0 1 0 1 0 1
1 1 1 1 1 0 1 0 1 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="460" y="380"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="340" y="180"/>
<p2 x="360" y="180"/>
</wire>
<wire>
<p1 x="400" y="180"/>
<p2 x="660" y="180"/>
</wire>
<wire>
<p1 x="340" y="260"/>
<p2 x="360" y="260"/>
</wire>
<wire>
<p1 x="400" y="260"/>
<p2 x="420" y="260"/>
</wire>
<wire>
<p1 x="460" y="260"/>
<p2 x="480" y="260"/>
</wire>
<wire>
<p1 x="520" y="260"/>
<p2 x="660" y="260"/>
</wire>
<wire>
<p1 x="340" y="340"/>
<p2 x="360" y="340"/>
</wire>
<wire>
<p1 x="400" y="340"/>
<p2 x="420" y="340"/>
</wire>
<wire>
<p1 x="460" y="340"/>
<p2 x="480" y="340"/>
</wire>
<wire>
<p1 x="520" y="340"/>
<p2 x="540" y="340"/>
</wire>
<wire>
<p1 x="580" y="340"/>
<p2 x="600" y="340"/>
</wire>
<wire>
<p1 x="640" y="340"/>
<p2 x="660" y="340"/>
</wire>
<wire>
<p1 x="340" y="220"/>
<p2 x="360" y="220"/>
</wire>
<wire>
<p1 x="400" y="220"/>
<p2 x="420" y="220"/>
</wire>
<wire>
<p1 x="460" y="220"/>
<p2 x="660" y="220"/>
</wire>
<wire>
<p1 x="340" y="300"/>
<p2 x="360" y="300"/>
</wire>
<wire>
<p1 x="400" y="300"/>
<p2 x="420" y="300"/>
</wire>
<wire>
<p1 x="460" y="300"/>
<p2 x="480" y="300"/>
</wire>
<wire>
<p1 x="520" y="300"/>
<p2 x="540" y="300"/>
</wire>
<wire>
<p1 x="580" y="300"/>
<p2 x="660" y="300"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>