fixed a merging issue

This commit is contained in:
hneemann 2018-04-14 14:14:15 +02:00
parent cf4ce1ec52
commit ea09282bc3
8 changed files with 160 additions and 18 deletions

View File

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

View File

@ -14,7 +14,7 @@ import de.neemann.digital.hdl.model2.Printable;
public interface Expression extends Printable {
/**
* Replaces a net with and expression
* Replaces a net with an expression
*
* @param net the net to replace
* @param expression the expression to use instead ot the net
@ -31,7 +31,7 @@ public interface Expression extends Printable {
}
/**
* Help er to check if a expression is a net reference
* Helper to check if an expression is a net reference
*
* @param expr the expression to check
* @param net the net

View File

@ -6,14 +6,16 @@
package de.neemann.digital.hdl.model2.optimizations;
import de.neemann.digital.hdl.model2.*;
import de.neemann.digital.hdl.model2.expression.ExprVarRange;
import de.neemann.digital.hdl.model2.expression.Expression;
import de.neemann.digital.hdl.model2.expression.Visitor;
import java.util.ArrayList;
/**
* Merges the bool expression by inlining nodes which also represent a bool expression.
*/
public class MergeAssignements implements Optimization {
public class MergeAssignments implements Optimization {
private HDLCircuit circuit;
private ArrayList<HDLNode> nodes;
@ -29,14 +31,18 @@ public class MergeAssignements implements Optimization {
for (int i = 0; i < nodes.size(); i++) {
HDLNode n1 = nodes.get(i);
if (n1 instanceof HDLNodeAssignment) {
for (HDLPort p : n1.getInputs()) {
HDLNodeAssignment host = (HDLNodeAssignment) n1;
for (HDLPort p : host.getInputs()) {
HDLNode n2 = searchCreator(p.getNet());
if (n2 != null && n2 instanceof HDLNodeAssignment) {
if (n2.getOutputs().size() == 1 && n2.getOutput().getNet().getInputs().size() == 1) {
nodes.set(i, merge((HDLNodeAssignment) n1, (HDLNodeAssignment) n2));
nodes.remove(n2);
wasOptimization = true;
break outer;
HDLNodeAssignment include = (HDLNodeAssignment) n2;
if (include.getOutputs().size() == 1 && include.getOutput().getNet().getInputs().size() == 1) {
if (allowedToReplaceNet(host.getExpression(), include.getOutput().getNet())) {
nodes.set(i, merge(host, include));
nodes.remove(n2);
wasOptimization = true;
break outer;
}
}
}
}
@ -45,6 +51,12 @@ public class MergeAssignements implements Optimization {
} while (wasOptimization);
}
private boolean allowedToReplaceNet(Expression expression, HDLNet net) {
final CheckVarRangeVisitor visitor = new CheckVarRangeVisitor(net);
expression.traverse(visitor);
return visitor.ok;
}
private HDLNodeAssignment merge(HDLNodeAssignment host, HDLNodeAssignment include) {
final Expression expression = host.getExpression();
final HDLNet obsoleteNet = include.getOutput().getNet();
@ -77,4 +89,23 @@ public class MergeAssignements implements Optimization {
return n;
return null;
}
private static final class CheckVarRangeVisitor implements Visitor {
private final HDLNet net;
private boolean ok;
private CheckVarRangeVisitor(HDLNet net) {
this.net = net;
ok = true;
}
@Override
public void visit(Expression expression) {
if (expression instanceof ExprVarRange) {
ExprVarRange evr = (ExprVarRange) expression;
if (evr.getNet() == net)
ok = false;
}
}
}
}

View File

@ -26,7 +26,7 @@ public class HDLModelTest extends TestCase {
public void testSimple() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
HDLCircuit hdl = getCircuit("dig/hdl/model2/comb.dig", null)
.apply(new MergeAssignements())
.apply(new MergeAssignments())
.apply(new NodeSorterExpressionBased())
.nameUnnamedSignals();
@ -215,7 +215,7 @@ public class HDLModelTest extends TestCase {
public void testConstantMerge() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
HDLCircuit hdl = getCircuit("dig/hdl/model2/constMerge.dig", null)
.apply(new MergeAssignements())
.apply(new MergeAssignments())
.apply(new MergeConstants())
.apply(new NameConstantSignals())
.apply(new NodeSorterExpressionBased())
@ -292,7 +292,7 @@ public class HDLModelTest extends TestCase {
public void testSplitter3() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter3.dig", null)
.apply(new ReplaceOneToMany())
.apply(new MergeAssignements())
.apply(new MergeAssignments())
.apply(new NodeSorterExpressionBased())
.nameUnnamedSignals();
@ -323,7 +323,7 @@ public class HDLModelTest extends TestCase {
public void testSplitter4() throws IOException, PinException, HDLException, NodeException, ElementNotFoundException {
HDLCircuit hdl = getCircuit("dig/hdl/model2/splitter4.dig", null)
.apply(new ReplaceOneToMany())
.apply(new MergeAssignements())
.apply(new MergeAssignments())
.apply(new NodeSorterExpressionBased())
.nameUnnamedSignals();

View File

@ -14,7 +14,6 @@ import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.model2.HDLModel;
import de.neemann.digital.hdl.model2.clock.ClockIntegratorGeneric;
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
import de.neemann.digital.hdl.model2.optimizations.MergeAssignements;
import de.neemann.digital.hdl.printer.CodePrinter;
import de.neemann.digital.hdl.printer.CodePrinterStr;
import de.neemann.digital.hdl.vhdl2.boards.ClockIntegratorARTIX7;

View File

@ -12,8 +12,6 @@ import de.neemann.digital.hdl.hgs.HGSEvalException;
import de.neemann.digital.hdl.model2.HDLCircuit;
import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.model2.HDLModel;
import de.neemann.digital.hdl.model2.optimizations.MergeConstants;
import de.neemann.digital.hdl.model2.optimizations.MergeAssignements;
import de.neemann.digital.hdl.printer.CodePrinterStr;
import de.neemann.digital.integration.ToBreakRunner;
import junit.framework.TestCase;

View File

@ -59,7 +59,7 @@ public class VHDLSimulatorTest extends TestCase {
File examples = new File(Resources.getRoot(), "/dig/hdl");
try {
int tested = new FileScanner(this::checkVHDLExport).noOutput().scan(examples);
assertEquals(45, tested);
assertEquals(46, tested);
} catch (FileScanner.SkipAllException e) {
// if ghdl is not installed its also ok
}

View File

@ -0,0 +1,114 @@
<?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>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="40" y="100"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="40" y="140"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="60" y="100"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
<elementAttributes>
<entry>
<string>Input Splitting</string>
<string>8</string>
</entry>
<entry>
<string>Output Splitting</string>
<string>4</string>
</entry>
</elementAttributes>
<pos x="160" y="120"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
<entry>
<string>Bits</string>
<int>4</int>
</entry>
</elementAttributes>
<pos x="220" y="120"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A B Y
0 0 0
0 1 0
1 0 0
1 1 1
0 0 0
0 255 0
255 0 0
255 255 15
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="80" y="180"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="40" y="100"/>
<p2 x="60" y="100"/>
</wire>
<wire>
<p1 x="120" y="120"/>
<p2 x="160" y="120"/>
</wire>
<wire>
<p1 x="180" y="120"/>
<p2 x="220" y="120"/>
</wire>
<wire>
<p1 x="40" y="140"/>
<p2 x="60" y="140"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>