added an error message if diodes are not used correctly

This commit is contained in:
hneemann 2017-04-17 09:08:20 +02:00
parent 0df2fbcd35
commit 532e17eae5
11 changed files with 270 additions and 172 deletions

View File

@ -1,96 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="120"/>
<rotate>0</rotate>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="600" y="120"/>
<rotate>0</rotate>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="200"/>
<rotate>0</rotate>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="200" y="120"/>
<rotate>0</rotate>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="340" y="120"/>
<rotate>0</rotate>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="480" y="120"/>
<rotate>0</rotate>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="260" y="120"/>
<p2 x="340" y="120"/>
</wire>
<wire>
<p1 x="400" y="120"/>
<p2 x="480" y="120"/>
</wire>
<wire>
<p1 x="540" y="120"/>
<p2 x="600" y="120"/>
</wire>
<wire>
<p1 x="140" y="120"/>
<p2 x="200" y="120"/>
</wire>
<wire>
<p1 x="140" y="200"/>
<p2 x="180" y="200"/>
</wire>
<wire>
<p1 x="320" y="200"/>
<p2 x="460" y="200"/>
</wire>
<wire>
<p1 x="180" y="200"/>
<p2 x="320" y="200"/>
</wire>
<wire>
<p1 x="180" y="140"/>
<p2 x="200" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="340" y="140"/>
</wire>
<wire>
<p1 x="460" y="140"/>
<p2 x="480" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="320" y="200"/>
</wire>
<wire>
<p1 x="180" y="140"/>
<p2 x="180" y="200"/>
</wire>
<wire>
<p1 x="460" y="140"/>
<p2 x="460" y="200"/>
</wire>
</wires>
<version>1</version>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D</string>
</entry>
</elementAttributes>
<pos x="140" y="120"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>D_2</string>
</entry>
</elementAttributes>
<pos x="580" y="80"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>C</string>
</entry>
</elementAttributes>
<pos x="140" y="200"/>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="200" y="120"/>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="340" y="120"/>
</visualElement>
<visualElement>
<elementName>D-T.dig</elementName>
<elementAttributes/>
<pos x="480" y="120"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>C D D_0 D_1 D_2
# clear all bits
C 0 0 x x
C 0 0 0 x
C 0 0 0 0
# fill with one
C 1 1 0 0
C 1 1 1 0
C 1 1 1 1
# fill with zero
C 0 0 1 1
C 0 0 0 1
C 0 0 0 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="480" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>D_0</string>
</entry>
</elementAttributes>
<pos x="300" y="80"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>D_1</string>
</entry>
</elementAttributes>
<pos x="440" y="80"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="260" y="120"/>
<p2 x="300" y="120"/>
</wire>
<wire>
<p1 x="400" y="120"/>
<p2 x="440" y="120"/>
</wire>
<wire>
<p1 x="140" y="120"/>
<p2 x="200" y="120"/>
</wire>
<wire>
<p1 x="540" y="120"/>
<p2 x="580" y="120"/>
</wire>
<wire>
<p1 x="440" y="120"/>
<p2 x="480" y="120"/>
</wire>
<wire>
<p1 x="300" y="120"/>
<p2 x="340" y="120"/>
</wire>
<wire>
<p1 x="140" y="200"/>
<p2 x="180" y="200"/>
</wire>
<wire>
<p1 x="180" y="200"/>
<p2 x="320" y="200"/>
</wire>
<wire>
<p1 x="320" y="200"/>
<p2 x="460" y="200"/>
</wire>
<wire>
<p1 x="180" y="140"/>
<p2 x="200" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="340" y="140"/>
</wire>
<wire>
<p1 x="460" y="140"/>
<p2 x="480" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="320" y="200"/>
</wire>
<wire>
<p1 x="580" y="80"/>
<p2 x="580" y="120"/>
</wire>
<wire>
<p1 x="180" y="140"/>
<p2 x="180" y="200"/>
</wire>
<wire>
<p1 x="440" y="80"/>
<p2 x="440" y="120"/>
</wire>
<wire>
<p1 x="460" y="140"/>
<p2 x="460" y="200"/>
</wire>
<wire>
<p1 x="300" y="80"/>
<p2 x="300" y="120"/>
</wire>
</wires>
</circuit>

View File

@ -4,6 +4,7 @@ import de.neemann.digital.core.ObservableValue;
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.core.element.PinDescription;
import static de.neemann.digital.core.element.PinInfo.input;
@ -27,7 +28,7 @@ public class DiodeBackward extends DiodeForeward {
* @param attr the elements attributes
*/
public DiodeBackward(ElementAttributes attr) {
super(attr, DESCRIPTION);
super(attr, DESCRIPTION, PinDescription.PullResistor.pullUp);
}
@Override

View File

@ -1,10 +1,9 @@
package de.neemann.digital.core.pld;
import de.neemann.digital.core.*;
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.core.element.*;
import de.neemann.digital.core.wiring.bus.CommonBusValue;
import de.neemann.digital.lang.Lang;
import static de.neemann.digital.core.element.PinInfo.input;
@ -24,6 +23,7 @@ public class DiodeForeward implements Element, Observer {
private final ObservableValue output;
private final boolean blown;
private ObservableValue input;
private PinDescription.PullResistor requiredResistor;
/**
* Creates a new instance
@ -31,17 +31,19 @@ public class DiodeForeward implements Element, Observer {
* @param attr the elements attributes
*/
public DiodeForeward(ElementAttributes attr) {
this(attr, DESCRIPTION);
this(attr, DESCRIPTION, PinDescription.PullResistor.pullDown);
}
/**
* Creates a new instance
*
* @param attr the elements attributes
* @param description used to set the output pin description
* @param attr the elements attributes
* @param description used to set the output pin description
* @param requiredResistor resistor needed at the output net
*/
protected DiodeForeward(ElementAttributes attr, ElementTypeDescription description) {
output = new ObservableValue("out", 1, true).setPinDescription(description);
protected DiodeForeward(ElementAttributes attr, ElementTypeDescription description, PinDescription.PullResistor requiredResistor) {
output = new ObservableValue("out", 1, true).setPinDescription(description).setBidirectional();
this.requiredResistor = requiredResistor;
blown = attr.get(Keys.BLOWN);
if (blown)
output.set(1, true);
@ -50,6 +52,17 @@ public class DiodeForeward implements Element, Observer {
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
input = inputs.get(0).addObserverToValue(this).checkBits(1, null);
ObservableValue o = inputs.get(1);
if (o instanceof CommonBusValue) {
CommonBusValue cbv = (CommonBusValue) o;
if (cbv.getResistor().equals(requiredResistor))
return;
}
if (requiredResistor.equals(PinDescription.PullResistor.pullDown))
throw new NodeException(Lang.get("err_diodeNeedsPullDownResistorAtOutput"), output.asList());
else
throw new NodeException(Lang.get("err_diodeNeedsPullUpResistorAtOutput"), output.asList());
}
@Override

View File

@ -8,6 +8,7 @@ import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.lang.Lang;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
@ -47,23 +48,31 @@ public class TestResult {
*/
public TestResult create(Model model) throws TestingDataException, NodeException {
allPassed = true;
HashSet<String> usedSignals = new HashSet<>();
ArrayList<TestSignal> inputs = new ArrayList<>();
for (Signal s : model.getInputs()) {
final int index = getIndexOf(s.getName());
if (index >= 0)
if (index >= 0) {
inputs.add(new TestSignal(index, s.getValue()));
usedSignals.add(s.getName());
}
}
for (Clock c : model.getClocks()) {
final int index = getIndexOf(c.getLabel());
if (index >= 0)
if (index >= 0) {
inputs.add(new TestSignal(index, c.getClockOutput()));
usedSignals.add(c.getLabel());
}
}
ArrayList<TestSignal> outputs = new ArrayList<>();
for (Signal s : model.getOutputs()) {
final int index = getIndexOf(s.getName());
if (index >= 0)
if (index >= 0) {
outputs.add(new TestSignal(index, s.getValue()));
usedSignals.add(s.getName());
}
}
if (inputs.size() == 0)
@ -72,6 +81,10 @@ public class TestResult {
if (outputs.size() == 0)
throw new TestingDataException(Lang.get("err_noTestOutputSignalsDefined"));
for (String name : names)
if (!usedSignals.contains(name))
throw new TestingDataException(Lang.get("err_testSignal_N_notFound", name));
model.init();
for (Value[] rowWithDontCare : lines) {

View File

@ -338,8 +338,8 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.</string
Wird verwendet um ein "Wired And" zu implementieren.
Innerhalb der Simulation verhält sich eine Diode wie ein aktives Gatter mit dreiwerteiger Wertetabelle:
Ist der Eingang 0 ist auch der Ausgang 0. In den anderen Fällen (1 und hochohmig) ist der Ausgang hochohmig (High Z).
Damit können sich antiparallele zusammen geschaltete Dioden gegenseiting im low-Zustand halten, was mit realen
Dioden nicht möglich ist.
Damit können sich antiparallel zusammen geschaltete Dioden gegenseitig im low-Zustand halten, was mit realen
Dioden nicht möglich ist. Daher ist am Ausgang ein Pull Up Widerstand erforderlich!
Es handelt sich um eine ideale Diode: In Durchlassrichtung gibt es keinen Spannungabfall über der Diode.</string>
<string name="elem_DiodeBackward_pin_in">Ist der Eingang 0 ist auch der Ausgang 0. In allen anderen Fällen ist der Ausgang hochohmig.</string>
<string name="elem_DiodeBackward_pin_out">Ist der Eingang 0 ist auch der Ausgang 0. In allen anderen Fällen ist der Ausgang hochohmig.</string>
@ -348,8 +348,8 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.</string
Wird verwendet um ein "Wired Or" zu implementieren.
Innerhalb der Simulation verhält sich eine Diode wie ein aktives Gatter mit dreiwerteiger Wertetabelle:
Ist der Eingang 1 ist auch der Ausgang 1. In den anderen Fällen (0 und hochohmig) ist der Ausgang hochohmig (High Z).
Damit können sich antiparallel zusammen geschaltete Dioden gegenseiting im high-Zustand halten, was mit realen
Dioden nicht möglich ist.
Damit können sich antiparallel zusammen geschaltete Dioden gegenseitig im high-Zustand halten, was mit realen
Dioden nicht möglich ist. Daher ist am Ausgang ein Pull Down Widerstand erforderlich!
Es handelt sich um eine ideale Diode: In Durchlassrichtung gibt es keinen Spannungabfall über der Diode.</string>
<string name="elem_DiodeForeward_pin_in">Ist der Eingang 1 ist auch der Ausgang 1. In allen anderen Fällen ist der Ausgang hochohmig.</string>
<string name="elem_DiodeForeward_pin_out">Ist der Eingang 1 ist auch der Ausgang 1. In allen anderen Fällen ist der Ausgang hochohmig.</string>
@ -486,6 +486,9 @@ Es sind nur {1} Variablen erlaubt, es wurden jedoch {2} gefunden.</string>
<string name="err_minimizationFailed">Das Ergebnis der Minimierung ist nicht korrekt!
Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="err_toManyTestEntries">Zu viele Einträge in der Testdatenmatrix.</string>
<string name="err_diodeNeedsPullUpResistorAtOutput">Diode benötigt am Ausgang einen PullUp-Widerstand!</string>
<string name="err_diodeNeedsPullDownResistorAtOutput">Diode benötigt am Ausgang einen PullDown-Widerstand!</string>
<string name="err_testSignal_N_notFound">Testsignal {0} in der Schaltung nicht gefunden!</string>
<string name="key_AddrBits">Adress-Bits</string>
<string name="key_AddrBits_tt">Anzahl der Adress-Bits die verwendet werden.</string>

View File

@ -331,6 +331,8 @@
<string name="elem_DiodeBackward">Diode to Ground</string>
<string name="elem_DiodeBackward_tt">A simplified unidirectional diode, used to pull a wire to ground. It is used to implement a wired AND.
Is the input low, also the output is low. In the other cases (input is high or high z) the output is in high z state.
So two anti parallel connected diodes can keep each other in low state, which is not possible with real diodes.
To aviod such problems, it is necessary to connect a pull up resistor to the diods output.
So this is a ideal diode: There is no voltage drop across a forward-biased diode.</string>
<string name="elem_DiodeBackward_pin_in">If the input is low also the output is low. In all other cases the output is in high z state.</string>
<string name="elem_DiodeBackward_pin_out">If the input is low also the output is low. In all other cases the output is in high z state.</string>
@ -338,7 +340,8 @@
<string name="elem_DiodeForeward_tt">A simplified unidirectional diode, used to pull a wire to VDD. It is used to implement a wired OR.
In the simulation the diode behaves like an active gate with a trivalent truth table:
Is the input high, also the output is high. In all other cases (input is low or high z) the output is in high z state.
So two antiparallel connected diodes can keep each other in high state, which is not possible with real diodes.
So two anti parallel connected diodes can keep each other in high state, which is not possible with real diodes.
To aviod such problems, it is necessary to connect a pull down resistor to the diods output.
This is an ideal diode: There is no voltage drop across a forward-biased diode.</string>
<string name="elem_DiodeForeward_pin_in">If the input is high also the output is high. In all other cases the output is in high z state.</string>
<string name="elem_DiodeForeward_pin_out">If the input is high also the output is high. In all other cases the output is in high z state.</string>
@ -473,6 +476,9 @@ allowed are {1} variables but {2} are found.</string>
<string name="err_minimizationFailed">The result of the minimization is not correct!
The names of the variables may not be unique.</string>
<string name="err_toManyTestEntries">To many entries in the test data matrix.</string>
<string name="err_diodeNeedsPullUpResistorAtOutput">Diode needs a pull up resistor at its output!</string>
<string name="err_diodeNeedsPullDownResistorAtOutput">Diode needs a pull down resistor at its output!</string>
<string name="err_testSignal_N_notFound">Test signal {0} not found in the circuit!</string>
<string name="key_AddrBits">Address Bits</string>
<string name="key_AddrBits_tt">Number of address bits used.</string>

View File

@ -1,52 +0,0 @@
package de.neemann.digital.core.pld;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.ElementAttributes;
import junit.framework.TestCase;
/**
* Created by hneemann on 01.11.16.
*/
public class DirectionalDiodeTest extends TestCase {
public void testDiodeForeward() throws Exception {
ObservableValue a = new ObservableValue("a", 1);
DiodeForeward diodeForeward = new DiodeForeward(new ElementAttributes());
diodeForeward.setInputs(a.asList());
diodeForeward.init(null);
ObservableValues outputs = diodeForeward.getOutputs();
assertEquals(1, outputs.size());
ObservableValue output = outputs.get(0);
a.setBool(true);
assertEquals(false, output.isHighZ());
assertEquals(1, output.getValue());
a.setBool(false);
assertEquals(true, output.isHighZ());
}
public void testDiodeBackward() throws Exception {
ObservableValue a = new ObservableValue("a", 1);
DiodeBackward diodeBackward = new DiodeBackward(new ElementAttributes());
diodeBackward.setInputs(a.asList());
diodeBackward.init(null);
ObservableValues outputs = diodeBackward.getOutputs();
assertEquals(1, outputs.size());
ObservableValue output = outputs.get(0);
a.setBool(true);
assertEquals(true, output.isHighZ());
a.setBool(false);
assertEquals(false, output.isHighZ());
assertEquals(0, output.getValue());
}
}

View File

@ -29,7 +29,7 @@ public class TestExamples extends TestCase {
public void testDistExamples() throws Exception {
File examples = new File(Resources.getRoot().getParentFile().getParentFile(), "/main/dig");
assertEquals(111, new FileScanner(this::check).scan(examples));
assertEquals(71, testCasesInFiles);
assertEquals(72, testCasesInFiles);
}
/**
@ -39,8 +39,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(56, new FileScanner(this::check).scan(examples));
assertEquals(52, testCasesInFiles);
assertEquals(55, new FileScanner(this::check).scan(examples));
assertEquals(51, testCasesInFiles);
}

View File

@ -20,7 +20,7 @@
<string>Y</string>
</entry>
</elementAttributes>
<pos x="320" y="220"/>
<pos x="340" y="220"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
@ -29,9 +29,9 @@
<string>Testdata</string>
<testData>
<dataString>A Y
1 Z
1 1
0 0
Z Z</dataString>
Z 1</dataString>
</testData>
</entry>
</elementAttributes>
@ -47,6 +47,11 @@ Z Z</dataString>
</elementAttributes>
<pos x="280" y="220"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="320" y="200"/>
</visualElement>
</visualElements>
<wires>
<wire>
@ -57,5 +62,13 @@ Z Z</dataString>
<p1 x="300" y="220"/>
<p2 x="320" y="220"/>
</wire>
<wire>
<p1 x="320" y="220"/>
<p2 x="340" y="220"/>
</wire>
<wire>
<p1 x="320" y="200"/>
<p2 x="320" y="220"/>
</wire>
</wires>
</circuit>

View File

@ -30,7 +30,7 @@
<string>Y</string>
</entry>
</elementAttributes>
<pos x="320" y="140"/>
<pos x="340" y="140"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
@ -40,14 +40,19 @@
<testData>
<dataString>A Y
1 1
0 Z
Z Z
0 0
Z 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="420" y="100"/>
</visualElement>
<visualElement>
<elementName>PullDown</elementName>
<elementAttributes/>
<pos x="320" y="160"/>
</visualElement>
</visualElements>
<wires>
<wire>
@ -58,5 +63,13 @@ Z Z
<p1 x="300" y="140"/>
<p2 x="320" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="340" y="140"/>
</wire>
<wire>
<p1 x="320" y="140"/>
<p2 x="320" y="160"/>
</wire>
</wires>
</circuit>