Optimized switch creation by detecting more simple switches.

This commit is contained in:
hneemann 2017-04-15 13:33:13 +02:00
parent 8ef847e056
commit 46e8891d26
12 changed files with 78 additions and 52 deletions

View File

@ -16,6 +16,7 @@ public class ObservableValue extends Observable implements PinDescription {
private long value;
private boolean highZ;
private boolean bidirectional;
private boolean isConstant = false;
private String description;
/**
@ -47,43 +48,52 @@ public class ObservableValue extends Observable implements PinDescription {
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
* @return this for chained calls
*/
public ObservableValue setValue(long value) {
value = getValueBits(value);
if (this.value != value) {
this.value = value;
if (!highZ)
fireHasChanged();
}
set(value, false);
return this;
}
/**
* Sets the highZ state of this value
*
* @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
* Sets the value and highZ state and fires an event if value has changed.
*
* @param value the value
* @param highZ highZ state
* @return this for chained calls
*/
public void set(long value, boolean highZ) {
setValue(value);
setHighZ(highZ);
public ObservableValue set(long value, boolean highZ) {
value = getValueBits(value);
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.
*
* @param bidirectional true if value is bidirectional
* @return this for chained calls
*/
public ObservableValue setBidirectional(boolean bidirectional) {
this.bidirectional = bidirectional;
public ObservableValue setBidirectional() {
this.bidirectional = true;
return this;
}
/**
* @return true if value is bidirectional
*/
public boolean isBidirectional() {
return bidirectional;
}
@Override
public String getDescription() {
if (description != null)

View File

@ -35,6 +35,7 @@ public class Const implements Element {
public Const(ElementAttributes attributes) {
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
output.setValue(attributes.get(Keys.VALUE));
output.setConstant();
}
@Override

View File

@ -34,6 +34,7 @@ public class Ground implements Element {
public Ground(ElementAttributes attributes) {
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
output.setValue(0);
output.setConstant();
}
@Override

View File

@ -34,6 +34,7 @@ public class VDD implements Element {
public VDD(ElementAttributes attributes) {
output = new ObservableValue("out", attributes.get(Keys.BITS)).setPinDescription(DESCRIPTION);
output.setValue(-1);
output.setConstant();
}
@Override

View File

@ -158,7 +158,7 @@ public class RAMDualPort extends Node implements Element, RAMInterface {
if (ld) {
output.set(memory.getDataWord(addr), false);
} else {
output.setHighZ(true);
output.set(0, true);
}
}

View File

@ -48,7 +48,7 @@ public class RAMSinglePort extends RAMDualPort {
@Override
protected ObservableValue createOutput() {
return super.createOutput()
.setBidirectional(true)
.setBidirectional()
.setPinDescription(DESCRIPTION);
}

View File

@ -62,7 +62,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
size = 1 << addrBits;
memory = new DataField(size);
label = attr.getCleanLabel();
dataOut = new ObservableValue("D", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
dataOut = new ObservableValue("D", bits, true).setPinDescription(DESCRIPTION).setBidirectional();
}
@Override
@ -92,7 +92,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
if (cs && oe) {
dataOut.set(memory.getDataWord(addr), false);
} else {
dataOut.setHighZ(true);
dataOut.set(0, true);
}
}

View File

@ -31,8 +31,8 @@ public class Diode implements Element, Observer {
* @param attr the elements attributes
*/
public Diode(ElementAttributes attr) {
cathode = new ObservableValue("cathode", 1, true).setBidirectional(true);
anode = new ObservableValue("anode", 1, true).setBidirectional(true);
cathode = new ObservableValue("cathode", 1, true).setBidirectional();
anode = new ObservableValue("anode", 1, true).setBidirectional();
blown = attr.get(Keys.BLOWN);
}

View File

@ -47,10 +47,8 @@ public class Switch implements Element, Observer {
public Switch(ElementAttributes attr, boolean closed) {
bits = attr.getBits();
this.closed = closed;
output1 = new ObservableValue("out1", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
output2 = new ObservableValue("out2", bits, true).setPinDescription(DESCRIPTION).setBidirectional(true);
output1.set(0, true);
output2.set(0, true);
output1 = new ObservableValue("out1", bits, true).setPinDescription(DESCRIPTION).setBidirectional().set(0, true);
output2 = new ObservableValue("out2", bits, true).setPinDescription(DESCRIPTION).setBidirectional().set(0, true);
}
@Override
@ -59,7 +57,18 @@ public class Switch implements Element, Observer {
ObservableValue input2 = inputs.get(1).addObserverToValue(this).checkBits(bits, null);
if (input1 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 {
switchModel = new SimpleSwitch(input1, output2);
}
@ -116,14 +125,14 @@ public class Switch implements Element, Observer {
/**
* @return output 1
*/
public ObservableValue getOutput1() {
ObservableValue getOutput1() {
return output1;
}
/**
* @return output 2
*/
public ObservableValue getOutput2() {
ObservableValue getOutput2() {
return output2;
}

View File

@ -30,14 +30,14 @@ public final class CommonBusValue extends ObservableValue implements Observer {
*
* @param handler the handler
*/
public void setHandler(AbstractBusHandler handler) {
void setHandler(AbstractBusHandler 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));
hasChanged();
}
@ -55,4 +55,16 @@ public final class CommonBusValue extends ObservableValue implements Observer {
public ObservableValue[] getInputs() {
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;
}
}

View File

@ -218,7 +218,7 @@ public final class SingleValueDialog extends JDialog {
SingleValueDialog svd = new SingleValueDialog(pos, value);
if (svd.showDialog()) {
if (svd.getSelectedFormat().equals(InMode.HIGHZ)) {
modelSync.access(() -> value.setHighZ(true));
modelSync.access(() -> value.set(0, true));
} else {
modelSync.access(() -> value.set(svd.editValue, false));
}

View File

@ -80,7 +80,7 @@ public class GraphicCard extends Node implements Element, RAMInterface {
dataOut = new ObservableValue("D", bits, true)
.setPinDescription(DESCRIPTION)
.setBidirectional(true);
.setBidirectional();
}
@Override
@ -135,7 +135,7 @@ public class GraphicCard extends Node implements Element, RAMInterface {
if (ld) {
dataOut.set(memory.getDataWord(addr), false);
} else {
dataOut.setHighZ(true);
dataOut.set(0, true);
}
}