allows testing of circuits using high-z inputs which are bidirectional.

This commit is contained in:
hneemann 2018-02-20 12:55:43 +01:00
parent 5fe0892634
commit 55b7ba5b27
7 changed files with 193 additions and 6 deletions

View File

@ -9,6 +9,7 @@ public final class Signal implements Comparable<Signal> {
private final Setter setter;
private IntFormat format = IntFormat.def;
private String pinNumber;
private ObservableValue bidirectionalReader;
/**
* Creates a new Instance
@ -138,6 +139,24 @@ public final class Signal implements Comparable<Signal> {
return setter;
}
/**
* If a signal is bidirectional the input is set.
*
* @param bidirectionalReader the corresponding input value
* @return this for chained calls
*/
public Signal setBidirectionalReader(ObservableValue bidirectionalReader) {
this.bidirectionalReader = bidirectionalReader;
return this;
}
/**
* @return the bidirectional reader, maybe null
*/
public ObservableValue getBidirectionalReader() {
return bidirectionalReader;
}
/**
* Setter interface to set a value
*/

View File

@ -5,7 +5,6 @@ import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.lang.Lang;
/**
* The Input
@ -41,6 +40,7 @@ public class In implements Element {
private final String pinNumber;
private final IntFormat format;
private Model model;
private ObservableValue input;
/**
* Create a new instance
@ -53,13 +53,15 @@ public class In implements Element {
pinNumber = attributes.get(Keys.PINNUMBER);
output = new ObservableValue("out", attributes.get(Keys.BITS), highZ).setPinDescription(DESCRIPTION).setPinNumber(pinNumber);
output.set(value.getValue(), value.isHighZ());
if (highZ) output.setBidirectional();
label = attributes.getCleanLabel();
format = attributes.get(Keys.INT_FORMAT);
}
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
throw new NodeException(Lang.get("err_noInputsAvailable"));
// if input is bidirectional the value is given to read the pins state!
input = inputs.get(0);
}
@Override
@ -71,6 +73,7 @@ public class In implements Element {
public void registerNodes(Model model) {
model.addInput(new Signal(label, output, output::set)
.setPinNumber(pinNumber)
.setBidirectionalReader(input)
.setFormat(format));
this.model = model;
}

View File

@ -59,13 +59,24 @@ public class TestExecutor {
HashSet<String> usedSignals = new HashSet<>();
inputs = new ArrayList<>();
outputs = new ArrayList<>();
for (Signal s : model.getInputs()) {
final int index = getIndexOf(s.getName());
if (index >= 0) {
inputs.add(new TestSignal(index, s.getValue()));
addTo(usedSignals, s.getName());
}
ObservableValue outValue = s.getBidirectionalReader();
if (outValue != null) {
final String outName = s.getName() + "_out";
final int inIndex = getIndexOf(outName);
if (inIndex >= 0) {
outputs.add(new TestSignal(inIndex, outValue));
addTo(usedSignals, outName);
}
}
}
for (Clock c : model.getClocks()) {
final int index = getIndexOf(c.getLabel());
if (index >= 0) {
@ -74,7 +85,6 @@ public class TestExecutor {
}
}
outputs = new ArrayList<>();
for (Signal s : model.getOutputs()) {
final int index = getIndexOf(s.getName());
if (index >= 0) {

View File

@ -1360,7 +1360,8 @@ werden: "let U=A+B, let V=A*B"</string>
<head><style>pre { background-color: #E0E0E0;}</style></head>
<body>
<p>Die erste Zeile muss, durch ein Leerzeichen getrennt, die
Ein- und Ausgänge auflisten. In den folgenden Zeilen stehen dann die Sollwerte.
Ein- und Ausgänge auflisten, die verwendet werden sollen.
In den folgenden Zeilen stehen dann die Sollwerte.
Dabei steht ein 'X' für Don't Care, und ein 'Z' für hochohmig.
Wird der Wert 'C' verwendet, werden zunächst alle anderen Werte gesetzt, dann wird ein
Taktzyklus durchgeführt, und erst daran anschließend werden die Werte verglichen.
@ -1413,6 +1414,22 @@ loop(a,16)
end loop
</pre>
<p>Ein Eingang, welcher hochhomige Werte erlaubt, kann auch als Testausgang verwendet werden.
In diesem Fall kann der Signalname mit einem nachgestellten '_out' verwendet werden, um den
aktuellen Wert zurückzulesen und zu überprüfen. Dazu muss der entsprechende Eingang auf
hochohmig ('Z') gesetzt sein.</p>
<pre>OE CLK D D_out
0 0 0 0
0 C 1 1
1 0 z 1
0 C 0 0
1 0 z 0
</pre>
<p>Die Schaltung zu diesem Test hat nur einen Eingang 'D', welcher aber hochohmig sein kann.
Daher steht auch das Signal 'D_out' zur Verfügung, um in diesem Fall den Wert zu prüfen.</p>
</body></html>]]></string>
</resources>

View File

@ -1400,6 +1400,21 @@ loop(a,16)
end loop
</pre>
<p>An input that allows high impedance as a value can also be used as a test output.
In this case, the signal name can be used with a trailing "_out" to read back and check the current value.
For this, the corresponding input must be set to high impedance ('Z').</p>
<pre>OE CLK D D_out
0 0 0 0
0 C 1 1
1 0 z 1
0 C 0 0
1 0 z 0
</pre>
<p>The circuit for this test has only one input 'D', but which can be high impedance state.
Therefore, the signal 'D_out' is also available to check the value in this case.</p>
</body></html>]]></string>
</resources>

View File

@ -40,8 +40,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(121, new FileScanner(this::check).scan(examples));
assertEquals(110, testCasesInFiles);
assertEquals(122, new FileScanner(this::check).scan(examples));
assertEquals(111, testCasesInFiles);
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>D_FF</elementName>
<elementAttributes/>
<pos x="440" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
<entry>
<string>isHighZ</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="380" y="180"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
<entry>
<string>flipSelPos</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="420" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>OE</string>
</entry>
</elementAttributes>
<pos x="380" y="140"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>CLK</string>
</entry>
</elementAttributes>
<pos x="380" y="220"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>OE CLK D D_out
0 0 0 0
0 C 1 1
1 0 z 1
0 C 0 0
1 0 z 0</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="400" y="260"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="380" y="180"/>
<p2 x="420" y="180"/>
</wire>
<wire>
<p1 x="500" y="180"/>
<p2 x="520" y="180"/>
</wire>
<wire>
<p1 x="420" y="180"/>
<p2 x="440" y="180"/>
</wire>
<wire>
<p1 x="420" y="100"/>
<p2 x="520" y="100"/>
</wire>
<wire>
<p1 x="420" y="200"/>
<p2 x="440" y="200"/>
</wire>
<wire>
<p1 x="380" y="140"/>
<p2 x="400" y="140"/>
</wire>
<wire>
<p1 x="380" y="220"/>
<p2 x="420" y="220"/>
</wire>
<wire>
<p1 x="420" y="100"/>
<p2 x="420" y="120"/>
</wire>
<wire>
<p1 x="420" y="160"/>
<p2 x="420" y="180"/>
</wire>
<wire>
<p1 x="420" y="200"/>
<p2 x="420" y="220"/>
</wire>
<wire>
<p1 x="520" y="100"/>
<p2 x="520" y="180"/>
</wire>
</wires>
</circuit>