mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-28 15:32:40 -04:00
Optimized switch creation by detecting more simple switches.
This commit is contained in:
parent
8ef847e056
commit
46e8891d26
@ -16,6 +16,7 @@ public class ObservableValue extends Observable implements PinDescription {
|
|||||||
private long value;
|
private long value;
|
||||||
private boolean highZ;
|
private boolean highZ;
|
||||||
private boolean bidirectional;
|
private boolean bidirectional;
|
||||||
|
private boolean isConstant = false;
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,43 +48,52 @@ public class ObservableValue extends Observable implements PinDescription {
|
|||||||
supportsHighZ = highZ;
|
supportsHighZ = highZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value and fires a event if value has changed.
|
* Makes this value a constant value
|
||||||
|
*/
|
||||||
|
public void setConstant() {
|
||||||
|
isConstant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this value is a constant
|
||||||
|
*/
|
||||||
|
public boolean isConstant() {
|
||||||
|
return isConstant;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value and fires an event if value has changed.
|
||||||
|
* Also sets this value to low Z
|
||||||
*
|
*
|
||||||
* @param value the new value
|
* @param value the new value
|
||||||
* @return this for chained calls
|
* @return this for chained calls
|
||||||
*/
|
*/
|
||||||
public ObservableValue setValue(long value) {
|
public ObservableValue setValue(long value) {
|
||||||
value = getValueBits(value);
|
set(value, false);
|
||||||
if (this.value != value) {
|
|
||||||
this.value = value;
|
|
||||||
if (!highZ)
|
|
||||||
fireHasChanged();
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the highZ state of this value
|
* Sets the value and highZ state and fires an event if value has changed.
|
||||||
*
|
|
||||||
* @param highZ the new highZ state
|
|
||||||
*/
|
|
||||||
public void setHighZ(boolean highZ) {
|
|
||||||
if (this.highZ != highZ) {
|
|
||||||
this.highZ = highZ;
|
|
||||||
fireHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value and highZ state
|
|
||||||
*
|
*
|
||||||
* @param value the value
|
* @param value the value
|
||||||
* @param highZ highZ state
|
* @param highZ highZ state
|
||||||
|
* @return this for chained calls
|
||||||
*/
|
*/
|
||||||
public void set(long value, boolean highZ) {
|
public ObservableValue set(long value, boolean highZ) {
|
||||||
setValue(value);
|
value = getValueBits(value);
|
||||||
setHighZ(highZ);
|
if (highZ != this.highZ || (!highZ && (value != this.value))) {
|
||||||
|
|
||||||
|
if (isConstant)
|
||||||
|
throw new RuntimeException("tried to modify a constant value!");
|
||||||
|
|
||||||
|
this.highZ = highZ;
|
||||||
|
this.value = value;
|
||||||
|
fireHasChanged();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,21 +253,13 @@ public class ObservableValue extends Observable implements PinDescription {
|
|||||||
/**
|
/**
|
||||||
* Makes this value a bidirectional value.
|
* Makes this value a bidirectional value.
|
||||||
*
|
*
|
||||||
* @param bidirectional true if value is bidirectional
|
|
||||||
* @return this for chained calls
|
* @return this for chained calls
|
||||||
*/
|
*/
|
||||||
public ObservableValue setBidirectional(boolean bidirectional) {
|
public ObservableValue setBidirectional() {
|
||||||
this.bidirectional = bidirectional;
|
this.bidirectional = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if value is bidirectional
|
|
||||||
*/
|
|
||||||
public boolean isBidirectional() {
|
|
||||||
return bidirectional;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
if (description != null)
|
if (description != null)
|
||||||
|
@ -35,6 +35,7 @@ public class Const implements Element {
|
|||||||
public Const(ElementAttributes attributes) {
|
public Const(ElementAttributes attributes) {
|
||||||
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
||||||
output.setValue(attributes.get(Keys.VALUE));
|
output.setValue(attributes.get(Keys.VALUE));
|
||||||
|
output.setConstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,7 @@ public class Ground implements Element {
|
|||||||
public Ground(ElementAttributes attributes) {
|
public Ground(ElementAttributes attributes) {
|
||||||
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
||||||
output.setValue(0);
|
output.setValue(0);
|
||||||
|
output.setConstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,7 @@ public class VDD implements Element {
|
|||||||
public VDD(ElementAttributes attributes) {
|
public VDD(ElementAttributes attributes) {
|
||||||
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
|
||||||
output.setValue(-1);
|
output.setValue(-1);
|
||||||
|
output.setConstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,7 +158,7 @@ public class RAMDualPort extends Node implements Element, RAMInterface {
|
|||||||
if (ld) {
|
if (ld) {
|
||||||
output.set(memory.getDataWord(addr), false);
|
output.set(memory.getDataWord(addr), false);
|
||||||
} else {
|
} else {
|
||||||
output.setHighZ(true);
|
output.set(0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public class RAMSinglePort extends RAMDualPort {
|
|||||||
@Override
|
@Override
|
||||||
protected ObservableValue createOutput() {
|
protected ObservableValue createOutput() {
|
||||||
return super.createOutput()
|
return super.createOutput()
|
||||||
.setBidirectional(true)
|
.setBidirectional()
|
||||||
.setPinDescription(DESCRIPTION);
|
.setPinDescription(DESCRIPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
size = 1 << addrBits;
|
size = 1 << addrBits;
|
||||||
memory = new DataField(size);
|
memory = new DataField(size);
|
||||||
label = attr.getCleanLabel();
|
label = attr.getCleanLabel();
|
||||||
dataOut = new ObservableValue("D", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
|
dataOut = new ObservableValue("D", bits, true).setPinDescription(DESCRIPTION).setBidirectional();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,7 +92,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
if (cs && oe) {
|
if (cs && oe) {
|
||||||
dataOut.set(memory.getDataWord(addr), false);
|
dataOut.set(memory.getDataWord(addr), false);
|
||||||
} else {
|
} else {
|
||||||
dataOut.setHighZ(true);
|
dataOut.set(0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ public class Diode implements Element, Observer {
|
|||||||
* @param attr the elements attributes
|
* @param attr the elements attributes
|
||||||
*/
|
*/
|
||||||
public Diode(ElementAttributes attr) {
|
public Diode(ElementAttributes attr) {
|
||||||
cathode = new ObservableValue("cathode", 1, true).setBidirectional(true);
|
cathode = new ObservableValue("cathode", 1, true).setBidirectional();
|
||||||
anode = new ObservableValue("anode", 1, true).setBidirectional(true);
|
anode = new ObservableValue("anode", 1, true).setBidirectional();
|
||||||
blown = attr.get(Keys.BLOWN);
|
blown = attr.get(Keys.BLOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,8 @@ public class Switch implements Element, Observer {
|
|||||||
public Switch(ElementAttributes attr, boolean closed) {
|
public Switch(ElementAttributes attr, boolean closed) {
|
||||||
bits = attr.getBits();
|
bits = attr.getBits();
|
||||||
this.closed = closed;
|
this.closed = closed;
|
||||||
output1 = new ObservableValue("out1", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
|
output1 = new ObservableValue("out1", bits, true).setPinDescription(DESCRIPTION).setBidirectional().set(0, true);
|
||||||
output2 = new ObservableValue("out2", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
|
output2 = new ObservableValue("out2", bits, true).setPinDescription(DESCRIPTION).setBidirectional().set(0, true);
|
||||||
output1.set(0, true);
|
|
||||||
output2.set(0, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -59,7 +57,18 @@ public class Switch implements Element, Observer {
|
|||||||
ObservableValue input2 = inputs.get(1).addObserverToValue(this).checkBits(bits, null);
|
ObservableValue input2 = inputs.get(1).addObserverToValue(this).checkBits(bits, null);
|
||||||
if (input1 instanceof CommonBusValue) {
|
if (input1 instanceof CommonBusValue) {
|
||||||
if (input2 instanceof CommonBusValue) {
|
if (input2 instanceof CommonBusValue) {
|
||||||
switchModel = new RealSwitch((CommonBusValue) input1, (CommonBusValue) input2);
|
final CommonBusValue in1 = (CommonBusValue) input1;
|
||||||
|
final CommonBusValue in2 = (CommonBusValue) input2;
|
||||||
|
ObservableValue constant = in1.searchConstant();
|
||||||
|
if (constant != null)
|
||||||
|
switchModel = new SimpleSwitch(constant, output2);
|
||||||
|
else {
|
||||||
|
constant = in2.searchConstant();
|
||||||
|
if (constant != null)
|
||||||
|
switchModel = new SimpleSwitch(constant, output1);
|
||||||
|
else
|
||||||
|
switchModel = new RealSwitch(in1, in2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switchModel = new SimpleSwitch(input1, output2);
|
switchModel = new SimpleSwitch(input1, output2);
|
||||||
}
|
}
|
||||||
@ -116,14 +125,14 @@ public class Switch implements Element, Observer {
|
|||||||
/**
|
/**
|
||||||
* @return output 1
|
* @return output 1
|
||||||
*/
|
*/
|
||||||
public ObservableValue getOutput1() {
|
ObservableValue getOutput1() {
|
||||||
return output1;
|
return output1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return output 2
|
* @return output 2
|
||||||
*/
|
*/
|
||||||
public ObservableValue getOutput2() {
|
ObservableValue getOutput2() {
|
||||||
return output2;
|
return output2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,14 +30,14 @@ public final class CommonBusValue extends ObservableValue implements Observer {
|
|||||||
*
|
*
|
||||||
* @param handler the handler
|
* @param handler the handler
|
||||||
*/
|
*/
|
||||||
public void setHandler(AbstractBusHandler handler) {
|
void setHandler(AbstractBusHandler handler) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the handler. SO this net is isolated to a single simple net.
|
* Resets the handler. So this net is isolated to a single simple net.
|
||||||
*/
|
*/
|
||||||
public void resetHandler() {
|
void resetHandler() {
|
||||||
setHandler(new SingleBusHandler(obs, this, resistor, inputs));
|
setHandler(new SingleBusHandler(obs, this, resistor, inputs));
|
||||||
hasChanged();
|
hasChanged();
|
||||||
}
|
}
|
||||||
@ -55,4 +55,16 @@ public final class CommonBusValue extends ObservableValue implements Observer {
|
|||||||
public ObservableValue[] getInputs() {
|
public ObservableValue[] getInputs() {
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this net is a constant
|
||||||
|
*
|
||||||
|
* @return true if this is a constant
|
||||||
|
*/
|
||||||
|
public ObservableValue searchConstant() {
|
||||||
|
for (ObservableValue i : inputs)
|
||||||
|
if (i.isConstant())
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ public final class SingleValueDialog extends JDialog {
|
|||||||
SingleValueDialog svd = new SingleValueDialog(pos, value);
|
SingleValueDialog svd = new SingleValueDialog(pos, value);
|
||||||
if (svd.showDialog()) {
|
if (svd.showDialog()) {
|
||||||
if (svd.getSelectedFormat().equals(InMode.HIGHZ)) {
|
if (svd.getSelectedFormat().equals(InMode.HIGHZ)) {
|
||||||
modelSync.access(() -> value.setHighZ(true));
|
modelSync.access(() -> value.set(0, true));
|
||||||
} else {
|
} else {
|
||||||
modelSync.access(() -> value.set(svd.editValue, false));
|
modelSync.access(() -> value.set(svd.editValue, false));
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class GraphicCard extends Node implements Element, RAMInterface {
|
|||||||
|
|
||||||
dataOut = new ObservableValue("D", bits, true)
|
dataOut = new ObservableValue("D", bits, true)
|
||||||
.setPinDescription(DESCRIPTION)
|
.setPinDescription(DESCRIPTION)
|
||||||
.setBidirectional(true);
|
.setBidirectional();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -135,7 +135,7 @@ public class GraphicCard extends Node implements Element, RAMInterface {
|
|||||||
if (ld) {
|
if (ld) {
|
||||||
dataOut.set(memory.getDataWord(addr), false);
|
dataOut.set(memory.getDataWord(addr), false);
|
||||||
} else {
|
} else {
|
||||||
dataOut.setHighZ(true);
|
dataOut.set(0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user