mirror of
https://github.com/hneemann/Digital.git
synced 2025-08-04 02:08:00 -04:00
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:
commit
d69cea6d1d
@ -537,6 +537,7 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
|
|||||||
public HDLCircuit applyDefaultOptimizations() throws HDLException {
|
public HDLCircuit applyDefaultOptimizations() throws HDLException {
|
||||||
apply(new ReplaceOneToMany());
|
apply(new ReplaceOneToMany());
|
||||||
apply(new MergeAssignments());
|
apply(new MergeAssignments());
|
||||||
|
apply(new OptimizeExpressions(new ExprNot.OptimizeNotNot()));
|
||||||
apply(new InlineManyToOne());
|
apply(new InlineManyToOne());
|
||||||
apply(new RemoveConstantSignals());
|
apply(new RemoveConstantSignals());
|
||||||
apply(new MergeConstants()); // under certain circumstances there are still constants
|
apply(new MergeConstants()); // under certain circumstances there are still constants
|
||||||
|
@ -9,6 +9,7 @@ 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.ExprVar;
|
||||||
import de.neemann.digital.hdl.model2.expression.Expression;
|
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.model2.expression.Visitor;
|
||||||
import de.neemann.digital.hdl.printer.CodePrinter;
|
import de.neemann.digital.hdl.printer.CodePrinter;
|
||||||
|
|
||||||
@ -80,4 +81,12 @@ public class HDLNodeAssignment extends HDLNode {
|
|||||||
return getOutput().getNet();
|
return getOutput().getNet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizes the expression
|
||||||
|
*
|
||||||
|
* @param eo the optimizer
|
||||||
|
*/
|
||||||
|
public void optimize(ExpressionOptimizer eo) {
|
||||||
|
expression = eo.optimize(expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,4 +53,25 @@ public class ExprNot implements Expression {
|
|||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
expr.traverse(visitor);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,4 +93,13 @@ public class ExprOperate implements Expression {
|
|||||||
for (Expression o : operands)
|
for (Expression o : operands)
|
||||||
o.traverse(visitor);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,15 @@ public interface Expression extends Printable {
|
|||||||
visitor.visit(this);
|
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
|
* Helper to check if an expression is a net reference
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -300,7 +300,13 @@ public class VerilogCreator {
|
|||||||
out.print(value(constant));
|
out.print(value(constant));
|
||||||
} else if (expression instanceof ExprNot) {
|
} else if (expression instanceof ExprNot) {
|
||||||
out.print("~ ");
|
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) {
|
} else if (expression instanceof ExprOperate) {
|
||||||
out.print("(");
|
out.print("(");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
@ -290,7 +290,13 @@ public class VHDLCreator {
|
|||||||
out.print(value(constant));
|
out.print(value(constant));
|
||||||
} else if (expression instanceof ExprNot) {
|
} else if (expression instanceof ExprNot) {
|
||||||
out.print("NOT ");
|
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) {
|
} else if (expression instanceof ExprOperate) {
|
||||||
out.print("(");
|
out.print("(");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
281
src/test/resources/dig/test/vhdl/not.dig
Normal file
281
src/test/resources/dig/test/vhdl/not.dig
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user