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 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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
} }
} }

View File

@ -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);
} }

View File

@ -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);
} }
} }

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
}
} }

View File

@ -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));
} }

View File

@ -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);
} }
} }