mirror of
https://github.com/hneemann/Digital.git
synced 2025-08-03 17:58:28 -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 {
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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));
|
||||
} 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;
|
||||
|
@ -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;
|
||||
|
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