mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -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
|
# 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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()) {
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user