fixes a bug in the hdl input inverter handling, closes #592

This commit is contained in:
hneemann 2020-12-28 13:01:07 +01:00
parent 899680b6ee
commit 426eb6e29d
7 changed files with 377 additions and 34 deletions

View File

@ -19,7 +19,6 @@ import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.core.wiring.Splitter;
import de.neemann.digital.draw.elements.*;
import de.neemann.digital.draw.library.GenericInitCode;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.draw.model.Net;
import de.neemann.digital.draw.model.NetList;
import de.neemann.digital.gui.components.data.DummyElement;
@ -147,18 +146,6 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
for (HDLNet n : listOfNets)
n.checkPinControlUsage();
// fix inverted inputs
ArrayList<HDLNode> newNodes = new ArrayList<>();
for (HDLNode n : nodes) {
InverterConfig iv = n.getElementAttributes().get(Keys.INVERTER_CONFIG);
if (!iv.isEmpty()) {
for (HDLPort p : n.getInputs())
if (iv.contains(p.getName()))
newNodes.add(createNot(p, n));
}
}
nodes.addAll(newNodes);
for (HDLPort i : inputs)
if (i.getNet() != null) {
i.getNet().setIsInput(i.getName());
@ -206,23 +193,28 @@ public class HDLCircuit implements Iterable<HDLNode>, HDLModel.BitProvider, Prin
nodes.add(oneToMany);
}
private HDLNode createNot(HDLPort p, HDLNode node) throws HDLException, NodeException, PinException {
final ElementAttributes attr = new ElementAttributes().setBits(p.getBits());
HDLNodeAssignment n = new HDLNodeAssignment(Not.DESCRIPTION.getName(), attr, name -> p.getBits());
HDLNet createNot(HDLNet inNet) throws HDLException, NodeException, PinException {
int bits = 1;
final ElementAttributes attr = new ElementAttributes().setBits(bits);
HDLNodeAssignment n = new HDLNodeAssignment(Not.DESCRIPTION.getName(), attr, name -> bits);
HDLNet outNet = new HDLNet(null);
listOfNets.add(outNet);
HDLNet inNet = p.getNet();
inNet.remove(p);
n.addPort(new HDLPort(Not.DESCRIPTION.getInputDescription(attr).get(0).getName(), inNet, HDLPort.Direction.IN, p.getBits()));
n.addPort(new HDLPort(Not.DESCRIPTION.getOutputDescriptions(attr).get(0).getName(), outNet, HDLPort.Direction.OUT, p.getBits()));
HDLPort notOut = new HDLPort(Not.DESCRIPTION.getOutputDescriptions(attr).get(0).getName(), outNet, HDLPort.Direction.OUT, 0);
n.addPort(notOut);
n.addPort(new HDLPort(Not.DESCRIPTION.getInputDescription(attr).get(0).getName(), inNet, HDLPort.Direction.IN, 0) {
@Override
public void setBits(int bits) {
super.setBits(bits);
notOut.setBits(bits);
}
});
p.setNet(outNet);
node.replaceNet(inNet, outNet);
n.setExpression(new ExprNot(new ExprVar(inNet)));
n.setExpression(new ExprNot(new ExprVar(n.getInputs().get(0).getNet())));
nodes.add(n);
return n;
return outNet;
}
private void addOutput(HDLPort port) {

View File

@ -19,6 +19,7 @@ import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
import de.neemann.digital.draw.library.ResolveGenerics;
import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
import de.neemann.digital.hdl.model2.expression.*;
@ -33,12 +34,12 @@ import static de.neemann.digital.draw.model.ModelCreator.fixGenerics;
* Ensures that every circuit is only processed one time.
*/
public class HDLModel implements Iterable<HDLCircuit> {
private ElementLibrary elementLibrary;
private HashMap<Circuit, HDLCircuit> circuitMap;
private final ElementLibrary elementLibrary;
private final HashMap<Circuit, HDLCircuit> circuitMap;
private final ResolveGenerics resolveGenerics = new ResolveGenerics();
private final HashMap<String, GenericsCache> genericInstanceNumbers;
private HDLCircuit main;
private Renaming renaming;
private ResolveGenerics resolveGenerics = new ResolveGenerics();
private HashMap<String, GenericsCache> genericInstanceNumbers;
/**
* Creates a new instance
@ -166,7 +167,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
return new ExprOperate(op, list);
}
private HDLNodeAssignment createExpression(VisualElement v, HDLCircuit parent, ElementTypeDescription td) throws HDLException, PinException {
private HDLNodeAssignment createExpression(VisualElement v, HDLCircuit parent, ElementTypeDescription td) throws HDLException, PinException, NodeException {
return addInputsOutputs(new HDLNodeAssignment(v.getElementName(),
v.getElementAttributes(),
new ObservableValuesBitsProvider(
@ -174,11 +175,15 @@ public class HDLModel implements Iterable<HDLCircuit> {
v, parent);
}
private <N extends HDLNode> N addInputsOutputs(N node, VisualElement v, HDLCircuit c) throws HDLException {
private <N extends HDLNode> N addInputsOutputs(N node, VisualElement v, HDLCircuit c) throws HDLException, NodeException, PinException {
for (Pin p : v.getPins()) {
HDLNet net = c.getNetOfPin(p);
switch (p.getDirection()) {
case input:
InverterConfig ic = v.getElementAttributes().get(Keys.INVERTER_CONFIG);
if (ic.contains(p.getName()))
net = c.createNot(net);
node.addPort(new HDLPort(p.getName(), net, HDLPort.Direction.IN, 0));
break;
case output:

View File

@ -62,7 +62,7 @@ public class VerilogSimulatorTest extends TestCase {
File examples = new File(Resources.getRoot(), "/dig/hdl");
try {
int tested = new FileScanner(this::checkVerilogExport).noOutput().scan(examples);
assertEquals(48, tested);
assertEquals(51, tested);
} catch (FileScanner.SkipAllException e) {
// if iverilog is not installed its also ok
}
@ -187,7 +187,7 @@ public class VerilogSimulatorTest extends TestCase {
}
private String getTime() {
DateFormat f = new SimpleDateFormat("YY-MM-dd_HH-mm_ss");
DateFormat f = new SimpleDateFormat("yy-MM-dd_HH-mm_ss");
return f.format(new Date());
}

View File

@ -54,7 +54,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(48, tested);
assertEquals(51, tested);
} catch (FileScanner.SkipAllException e) {
// if ghdl is not installed its also ok
}
@ -179,7 +179,7 @@ public class VHDLSimulatorTest extends TestCase {
}
private String getTime() {
DateFormat f = new SimpleDateFormat("YY-MM-dd_HH-mm_ss");
DateFormat f = new SimpleDateFormat("yy-MM-dd_HH-mm_ss");
return f.format(new Date());
}

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
</elementAttributes>
<pos x="-200" y="20"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="-200" y="80"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="-60" y="40"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C D Y
0 0 0
1 0 1
0 0 1
1 0 1
0 1 1
1 1 0</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="-180" y="100"/>
</visualElement>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>D</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="-140" y="40"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="-200" y="80"/>
<p2 x="-180" y="80"/>
</wire>
<wire>
<p1 x="-200" y="20"/>
<p2 x="-180" y="20"/>
</wire>
<wire>
<p1 x="-80" y="40"/>
<p2 x="-60" y="40"/>
</wire>
<wire>
<p1 x="-180" y="40"/>
<p2 x="-160" y="40"/>
</wire>
<wire>
<p1 x="-180" y="60"/>
<p2 x="-140" y="60"/>
</wire>
<wire>
<p1 x="-180" y="20"/>
<p2 x="-180" y="40"/>
</wire>
<wire>
<p1 x="-180" y="60"/>
<p2 x="-180" y="80"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="-200" y="20"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="-200" y="80"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="-60" y="40"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C D Y
0 0 0
1 0 3
0 0 3
1 0 3
0 1 3
1 1 2
0 0 2
1 0 3</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="-180" y="100"/>
</visualElement>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>D</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="-140" y="40"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="-200" y="80"/>
<p2 x="-180" y="80"/>
</wire>
<wire>
<p1 x="-200" y="20"/>
<p2 x="-180" y="20"/>
</wire>
<wire>
<p1 x="-80" y="40"/>
<p2 x="-60" y="40"/>
</wire>
<wire>
<p1 x="-180" y="40"/>
<p2 x="-160" y="40"/>
</wire>
<wire>
<p1 x="-180" y="60"/>
<p2 x="-140" y="60"/>
</wire>
<wire>
<p1 x="-180" y="20"/>
<p2 x="-180" y="40"/>
</wire>
<wire>
<p1 x="-180" y="60"/>
<p2 x="-180" y="80"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
</elementAttributes>
<pos x="-180" y="40"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="-280" y="60"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Q</string>
</entry>
</elementAttributes>
<pos x="-40" y="20"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C D Set Clr Q nQ
C 0 1 1 0 1
C 1 1 1 1 0
C 0 1 1 0 1
0 0 1 1 0 1
0 0 0 1 1 0
0 0 1 1 1 0
0 0 1 0 0 1
0 0 1 1 0 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="-200" y="120"/>
</visualElement>
<visualElement>
<elementName>D_FF_AS</elementName>
<elementAttributes>
<entry>
<string>inverterConfig</string>
<inverterConfig>
<string>Set</string>
<string>Clr</string>
</inverterConfig>
</entry>
</elementAttributes>
<pos x="-140" y="20"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>nQ</string>
</entry>
</elementAttributes>
<pos x="-40" y="60"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Set</string>
</entry>
</elementAttributes>
<pos x="-280" y="20"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Clr</string>
</entry>
</elementAttributes>
<pos x="-180" y="80"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="-180" y="80"/>
<p2 x="-160" y="80"/>
</wire>
<wire>
<p1 x="-80" y="20"/>
<p2 x="-40" y="20"/>
</wire>
<wire>
<p1 x="-280" y="20"/>
<p2 x="-160" y="20"/>
</wire>
<wire>
<p1 x="-180" y="40"/>
<p2 x="-140" y="40"/>
</wire>
<wire>
<p1 x="-80" y="40"/>
<p2 x="-60" y="40"/>
</wire>
<wire>
<p1 x="-280" y="60"/>
<p2 x="-140" y="60"/>
</wire>
<wire>
<p1 x="-60" y="60"/>
<p2 x="-40" y="60"/>
</wire>
<wire>
<p1 x="-60" y="40"/>
<p2 x="-60" y="60"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>