From ea09282bc3f5e92abbf1e9c4aed2ac1e53ac5b44 Mon Sep 17 00:00:00 2001 From: hneemann Date: Sat, 14 Apr 2018 14:14:15 +0200 Subject: [PATCH] fixed a merging issue --- .../digital/hdl/model2/HDLCircuit.java | 2 +- .../hdl/model2/expression/Expression.java | 4 +- ...ssignements.java => MergeAssignments.java} | 45 +++++-- .../digital/hdl/model2/HDLModelTest.java | 8 +- .../neemann/digital/hdl/vhdl2/ClockTest.java | 1 - .../digital/hdl/vhdl2/DescriptionTest.java | 2 - .../digital/hdl/vhdl2/VHDLSimulatorTest.java | 2 +- .../dig/hdl/model2/avoidVarRangeMerge.dig | 114 ++++++++++++++++++ 8 files changed, 160 insertions(+), 18 deletions(-) rename src/main/java/de/neemann/digital/hdl/model2/optimizations/{MergeAssignements.java => MergeAssignments.java} (57%) create mode 100644 src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java index 4b7f95693..ebbb8060b 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLCircuit.java @@ -524,7 +524,7 @@ public class HDLCircuit implements Iterable, 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 diff --git a/src/main/java/de/neemann/digital/hdl/model2/expression/Expression.java b/src/main/java/de/neemann/digital/hdl/model2/expression/Expression.java index cc14872ac..e4144f906 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/expression/Expression.java +++ b/src/main/java/de/neemann/digital/hdl/model2/expression/Expression.java @@ -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 diff --git a/src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignements.java b/src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignments.java similarity index 57% rename from src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignements.java rename to src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignments.java index 3560af26b..de29ff655 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignements.java +++ b/src/main/java/de/neemann/digital/hdl/model2/optimizations/MergeAssignments.java @@ -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 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; + } + } + } } diff --git a/src/test/java/de/neemann/digital/hdl/model2/HDLModelTest.java b/src/test/java/de/neemann/digital/hdl/model2/HDLModelTest.java index 9025825ae..2dcee8778 100644 --- a/src/test/java/de/neemann/digital/hdl/model2/HDLModelTest.java +++ b/src/test/java/de/neemann/digital/hdl/model2/HDLModelTest.java @@ -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(); diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/ClockTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/ClockTest.java index 9fd90b6b6..82d5015bf 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl2/ClockTest.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl2/ClockTest.java @@ -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; diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/DescriptionTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/DescriptionTest.java index bbb994f36..78e9a760f 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl2/DescriptionTest.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl2/DescriptionTest.java @@ -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; diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java index 4b984c2ed..0b28be7a1 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java @@ -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 } diff --git a/src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig b/src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig new file mode 100644 index 000000000..b505e1b39 --- /dev/null +++ b/src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig @@ -0,0 +1,114 @@ + + + 1 + + + + In + + + Label + A + + + Bits + 8 + + + + + + In + + + Label + B + + + Bits + 8 + + + + + + And + + + Bits + 8 + + + + + + Splitter + + + Input Splitting + 8 + + + Output Splitting + 4 + + + + + + Out + + + Label + Y + + + Bits + 4 + + + + + + Testcase + + + Testdata + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file