mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 07:48:29 -04:00
if high-z values are used, random bits are created
This commit is contained in:
parent
f7b1113a3f
commit
8ee40a3d49
@ -519,9 +519,9 @@ in der Speichermatrix gespeichert.}}</string>
|
||||
|
||||
# write all cells to one
|
||||
loop(n,16)
|
||||
bits(4,n) 0 1 0
|
||||
bits(4,n) 1 1 1
|
||||
bits(4,n) 0 1 1
|
||||
bits(4,n) 0 1 x
|
||||
bits(4,n) 1 1 x
|
||||
bits(4,n) 0 1 x
|
||||
end loop
|
||||
|
||||
# check all cells are one
|
||||
|
@ -9,6 +9,8 @@ import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.PinDescription;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -29,6 +31,8 @@ public class ObservableValue extends Observable implements PinDescription {
|
||||
private String description;
|
||||
private String pinNumber;
|
||||
private boolean isSwitchPin;
|
||||
// used to create random bits if high-z values are read
|
||||
private Random random;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -81,14 +81,16 @@ public abstract class AbstractBusHandler {
|
||||
long highz = -1;
|
||||
for (ObservableValue input : getInputs()) {
|
||||
highz &= input.getHighZ();
|
||||
value |= input.getValue();
|
||||
value |= input.getValueHighZIsZero();
|
||||
}
|
||||
|
||||
// check for a burn condition!
|
||||
for (ObservableValue input : getInputs()) {
|
||||
long bothDefine = ~(highz | input.getHighZ());
|
||||
if ((value & bothDefine) != (input.getValue() & bothDefine))
|
||||
if ((value & bothDefine) != (input.getValueHighZIsZero() & bothDefine)) {
|
||||
burn = State.burn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (getResistor()) {
|
||||
|
@ -336,8 +336,7 @@
|
||||
<string name="elem_VDD_pin_out">Dieser Ausgang gibt immer 1 aus.</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
|
||||
legen. Wird ein Eingang eines Gatters auf High-Z gesetzt, wird dieser Wert vom Simulator wie Null
|
||||
interpretiert.
|
||||
legen. Wird ein Eingang eines logischen Gatters auf High-Z gesetzt, ist der gelesene Wert undefiniert.
|
||||
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
|
||||
unbeschaltet bleibt. Daher sollte dies Element mit Bedacht eingesetzt werden.</string>
|
||||
|
@ -333,7 +333,7 @@
|
||||
<string name="elem_VDD_pin_out">This output always returns 1.</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.
|
||||
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
|
||||
occur if a digital input is not set to zero or one but remains unconnected.
|
||||
Therefore this element should be used with care.</string>
|
||||
|
@ -9,6 +9,7 @@ import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ObservableValueTest extends TestCase {
|
||||
|
||||
@ -52,13 +53,22 @@ public class ObservableValueTest extends TestCase {
|
||||
|
||||
public void testHighZ() {
|
||||
ObservableValue v = new ObservableValue("z", 4);
|
||||
check(0, 15, v.set(15, 15));
|
||||
check(14, 1, v.set(15, 1));
|
||||
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) {
|
||||
assertEquals(val, v.getValue());
|
||||
assertEquals(val, v.getValue() & ~z);
|
||||
assertEquals(z, v.getHighZ());
|
||||
}
|
||||
|
||||
@ -66,10 +76,10 @@ public class ObservableValueTest extends TestCase {
|
||||
ObservableValue v = new ObservableValue("z", 4)
|
||||
.setToHighZ()
|
||||
.addObserverToValue(Assert::fail);
|
||||
v.set(0,15);
|
||||
v.set(1,15);
|
||||
v.set(2,15);
|
||||
v.set(3,15);
|
||||
v.set(0, 15);
|
||||
v.set(1, 15);
|
||||
v.set(2, 15);
|
||||
v.set(3, 15);
|
||||
}
|
||||
|
||||
public void testChange() {
|
||||
@ -91,12 +101,12 @@ public class ObservableValueTest extends TestCase {
|
||||
|
||||
@Override
|
||||
public void hasChanged() {
|
||||
changed=true;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
private boolean isChanged() {
|
||||
final boolean c = changed;
|
||||
changed=false;
|
||||
changed = false;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import static de.neemann.digital.TestExecuter.IGNORE;
|
||||
import static de.neemann.digital.core.ObservableValues.ovs;
|
||||
|
||||
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());
|
||||
te.check(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
te.check(1, 5, 0, 0, 0, 0, 0, 1, 0, 1, 0);
|
||||
te.check(1, 15, 0, 0, 0, 0, 0, 1, 1, 1, 1);
|
||||
te.check(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
te.check(0, 0, 1, 0, 1, 0, 5, 0, 0, 0, 0);
|
||||
te.check(0, 0, 1, 1, 1, 1, 15, 0, 0, 0, 0);
|
||||
te.checkZ(1, 0, 0, 0, 0, 0, IGNORE, 0, 0, 0, 0);
|
||||
te.checkZ(1, 5, 0, 0, 0, 0, IGNORE, 1, 0, 1, 0);
|
||||
te.checkZ(1, 15, 0, 0, 0, 0, IGNORE, 1, 1, 1, 1);
|
||||
te.checkZ(0, 0, 0, 0, 0, 0, 0, IGNORE, IGNORE, IGNORE, IGNORE);
|
||||
te.checkZ(0, 0, 1, 0, 1, 0, 5, IGNORE, IGNORE, IGNORE, IGNORE);
|
||||
te.checkZ(0, 0, 1, 1, 1, 1, 15, IGNORE, IGNORE, IGNORE, IGNORE);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user