if high-z values are used, random bits are created

This commit is contained in:
hneemann 2020-11-17 20:51:49 +01:00
parent f7b1113a3f
commit 8ee40a3d49
7 changed files with 55 additions and 23 deletions

View File

@ -519,9 +519,9 @@ in der Speichermatrix gespeichert.}}</string>
# write all cells to one # write all cells to one
loop(n,16) loop(n,16)
bits(4,n) 0 1 0 bits(4,n) 0 1 x
bits(4,n) 1 1 1 bits(4,n) 1 1 x
bits(4,n) 0 1 1 bits(4,n) 0 1 x
end loop end loop
# check all cells are one # check all cells are one

View File

@ -9,6 +9,8 @@ import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.PinDescription; import de.neemann.digital.core.element.PinDescription;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import java.util.Random;
/** /**
* Represents all signal values in the simulator. * Represents all signal values in the simulator.
* There are some setters to set the value. Each bit of a value can be set to high z state. * There are some setters to set the value. Each bit of a value can be set to high z state.
@ -29,6 +31,8 @@ public class ObservableValue extends Observable implements PinDescription {
private String description; private String description;
private String pinNumber; private String pinNumber;
private boolean isSwitchPin; private boolean isSwitchPin;
// used to create random bits if high-z values are read
private Random random;
/** /**
* Creates a new instance. * Creates a new instance.
@ -122,11 +126,27 @@ public class ObservableValue extends Observable implements PinDescription {
} }
/** /**
* returns the actual value * Returns the current value.
* The high-z bits are set to a random value.
* *
* @return the value * @return the value
*/ */
public long getValue() { public long getValue() {
if (highZ != 0) {
if (random == null)
random = new Random();
return value | (random.nextLong() & highZ);
} else
return value;
}
/**
* Returns the current value
* The high-z bits are set to zero
*
* @return the value
*/
public long getValueHighZIsZero() {
return value; return value;
} }

View File

@ -81,14 +81,16 @@ public abstract class AbstractBusHandler {
long highz = -1; long highz = -1;
for (ObservableValue input : getInputs()) { for (ObservableValue input : getInputs()) {
highz &= input.getHighZ(); highz &= input.getHighZ();
value |= input.getValue(); value |= input.getValueHighZIsZero();
} }
// check for a burn condition! // check for a burn condition!
for (ObservableValue input : getInputs()) { for (ObservableValue input : getInputs()) {
long bothDefine = ~(highz | input.getHighZ()); long bothDefine = ~(highz | input.getHighZ());
if ((value & bothDefine) != (input.getValue() & bothDefine)) if ((value & bothDefine) != (input.getValueHighZIsZero() & bothDefine)) {
burn = State.burn; burn = State.burn;
break;
}
} }
switch (getResistor()) { switch (getResistor()) {

View File

@ -336,8 +336,7 @@
<string name="elem_VDD_pin_out">Dieser Ausgang gibt immer 1 aus.</string> <string name="elem_VDD_pin_out">Dieser Ausgang gibt immer 1 aus.</string>
<string name="elem_NotConnected">Nicht verbunden</string> <string name="elem_NotConnected">Nicht verbunden</string>
<string name="elem_NotConnected_tt">Dieses Element kann verwendet werden, um eine Leitung auf High-Z zu <string name="elem_NotConnected_tt">Dieses Element kann verwendet werden, um eine Leitung auf High-Z zu
legen. Wird ein Eingang eines Gatters auf High-Z gesetzt, wird dieser Wert vom Simulator wie Null legen. Wird ein Eingang eines logischen Gatters auf High-Z gesetzt, ist der gelesene Wert undefiniert.
interpretiert.
Zu beachten ist, dass es in der Realität in vielen Fällen zu überhöhter Stromaufnahme und gar zu Zu beachten ist, dass es in der Realität in vielen Fällen zu überhöhter Stromaufnahme und gar zu
Beschädigungen kommen kann, wenn ein Digitaleingang nicht auf Null oder Eins gesetzt wird, sondern Beschädigungen kommen kann, wenn ein Digitaleingang nicht auf Null oder Eins gesetzt wird, sondern
unbeschaltet bleibt. Daher sollte dies Element mit Bedacht eingesetzt werden.</string> unbeschaltet bleibt. Daher sollte dies Element mit Bedacht eingesetzt werden.</string>

View File

@ -333,7 +333,7 @@
<string name="elem_VDD_pin_out">This output always returns 1.</string> <string name="elem_VDD_pin_out">This output always returns 1.</string>
<string name="elem_NotConnected">Not Connected</string> <string name="elem_NotConnected">Not Connected</string>
<string name="elem_NotConnected_tt">This component can be used to set a line to High-Z. <string name="elem_NotConnected_tt">This component can be used to set a line to High-Z.
If an input of a gate is set to High-Z, the simulator interprets this value as zero. If an input of a logical gate is set to high-Z, the read value is undefined.
Note that in reality in many cases excessive current consumption and even damage can Note that in reality in many cases excessive current consumption and even damage can
occur if a digital input is not set to zero or one but remains unconnected. occur if a digital input is not set to zero or one but remains unconnected.
Therefore this element should be used with care.</string> Therefore this element should be used with care.</string>

View File

@ -9,6 +9,7 @@ import junit.framework.Assert;
import junit.framework.TestCase; import junit.framework.TestCase;
/** /**
*
*/ */
public class ObservableValueTest extends TestCase { public class ObservableValueTest extends TestCase {
@ -52,13 +53,22 @@ public class ObservableValueTest extends TestCase {
public void testHighZ() { public void testHighZ() {
ObservableValue v = new ObservableValue("z", 4); ObservableValue v = new ObservableValue("z", 4);
check(0, 15, v.set(15, 15));
check(14, 1, v.set(15, 1)); check(14, 1, v.set(15, 1));
check(12, 3, v.set(15, 3)); check(12, 3, v.set(15, 3));
v.set(15, 15);
long min = 15;
long max = 0;
for (int i = 0; i < 100; i++) {
long val = v.getValue();
if (val < min) min = val;
if (val > max) max = val;
}
assertTrue(max - min > 8);
} }
private void check(long val, long z, ObservableValue v) { private void check(long val, long z, ObservableValue v) {
assertEquals(val, v.getValue()); assertEquals(val, v.getValue() & ~z);
assertEquals(z, v.getHighZ()); assertEquals(z, v.getHighZ());
} }

View File

@ -11,6 +11,7 @@ import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementAttributes;
import junit.framework.TestCase; import junit.framework.TestCase;
import static de.neemann.digital.TestExecuter.IGNORE;
import static de.neemann.digital.core.ObservableValues.ovs; import static de.neemann.digital.core.ObservableValues.ovs;
public class BusSplitterTest extends TestCase { public class BusSplitterTest extends TestCase {
@ -30,12 +31,12 @@ public class BusSplitterTest extends TestCase {
TestExecuter te = new TestExecuter(model).setInputs(oe, d, d0, d1, d2, d3).setOutputs(out.getOutputs()); TestExecuter te = new TestExecuter(model).setInputs(oe, d, d0, d1, d2, d3).setOutputs(out.getOutputs());
te.check(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); te.checkZ(1, 0, 0, 0, 0, 0, IGNORE, 0, 0, 0, 0);
te.check(1, 5, 0, 0, 0, 0, 0, 1, 0, 1, 0); te.checkZ(1, 5, 0, 0, 0, 0, IGNORE, 1, 0, 1, 0);
te.check(1, 15, 0, 0, 0, 0, 0, 1, 1, 1, 1); te.checkZ(1, 15, 0, 0, 0, 0, IGNORE, 1, 1, 1, 1);
te.check(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); te.checkZ(0, 0, 0, 0, 0, 0, 0, IGNORE, IGNORE, IGNORE, IGNORE);
te.check(0, 0, 1, 0, 1, 0, 5, 0, 0, 0, 0); te.checkZ(0, 0, 1, 0, 1, 0, 5, IGNORE, IGNORE, IGNORE, IGNORE);
te.check(0, 0, 1, 1, 1, 1, 15, 0, 0, 0, 0); te.checkZ(0, 0, 1, 1, 1, 1, 15, IGNORE, IGNORE, IGNORE, IGNORE);
} }
} }