mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-09 12:56:02 -04:00
fixed a merging issue
This commit is contained in:
parent
cf4ce1ec52
commit
ea09282bc3
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
114
src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig
Normal file
114
src/test/resources/dig/hdl/model2/avoidVarRangeMerge.dig
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user