refactoring of async flip-flops

This commit is contained in:
hneemann 2017-11-11 09:36:44 +01:00
parent 5c0a9a073a
commit a8cf20e696
4 changed files with 30 additions and 134 deletions

View File

@ -62,7 +62,7 @@ public class FlipflopD extends Node implements Element {
throw new RuntimeException("wrong bit count given!");
}
private FlipflopD(ElementAttributes attributes, ObservableValue q, ObservableValue qn) {
FlipflopD(ElementAttributes attributes, ObservableValue q, ObservableValue qn) {
super(true);
bits = attributes.getBits();
this.q = q;
@ -138,4 +138,8 @@ public class FlipflopD extends Node implements Element {
public int getBits() {
return bits;
}
void setValue(long value) {
this.value = value;
}
}

View File

@ -1,7 +1,9 @@
package de.neemann.digital.core.flipflops;
import de.neemann.digital.core.*;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.BitsException;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
@ -14,13 +16,14 @@ import static de.neemann.digital.core.element.PinInfo.input;
*
* @author hneemann
*/
public class FlipflopDAsync extends Node implements Element {
public class FlipflopDAsync extends FlipflopD {
/**
* The D-FF description
*/
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription("D_FF_AS", FlipflopDAsync.class, input("Set"), input("D"), input("C"), input("Clr"))
= new ElementTypeDescription("D_FF_AS", FlipflopDAsync.class,
input("Set"), input("D"), input("C"), input("Clr"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
@ -28,17 +31,8 @@ public class FlipflopDAsync extends Node implements Element {
.addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final int bits;
private final boolean isProbe;
private final String label;
private ObservableValue setVal;
private ObservableValue clrVal;
private ObservableValue dVal;
private ObservableValue clockVal;
private ObservableValue q;
private ObservableValue qn;
private boolean lastClock;
private long value;
/**
* Creates a new instance
@ -46,76 +40,21 @@ public class FlipflopDAsync extends Node implements Element {
* @param attributes the attributes
*/
public FlipflopDAsync(ElementAttributes attributes) {
this(attributes,
new ObservableValue("Q", attributes.getBits()).setPinDescription(DESCRIPTION),
new ObservableValue("\u00ACQ", attributes.getBits()).setPinDescription(DESCRIPTION));
}
/**
* Creates a new D-FF with the given outputs!
*
* @param label the label
* @param q output
* @param qn inverted output
*/
public FlipflopDAsync(String label, ObservableValue q, ObservableValue qn) {
this(new ElementAttributes().set(Keys.LABEL, label).setBits(q.getBits()), q, qn);
if (qn.getBits() != q.getBits())
throw new RuntimeException("wrong bit count given!");
}
private FlipflopDAsync(ElementAttributes attributes, ObservableValue q, ObservableValue qn) {
super(true);
bits = attributes.getBits();
this.q = q;
this.qn = qn;
isProbe = attributes.get(Keys.VALUE_IS_PROBE);
label = attributes.getCleanLabel();
value = attributes.get(Keys.DEFAULT);
q.setValue(value);
qn.setValue(~value);
super(attributes);
}
@Override
public void readInputs() throws NodeException {
boolean clock = clockVal.getBool();
if (clock && !lastClock)
value = dVal.getValue();
lastClock = clock;
if (setVal.getBool()) value = -1;
else if (clrVal.getBool()) value = 0;
}
@Override
public void writeOutputs() throws NodeException {
q.setValue(value);
qn.setValue(~value);
super.readInputs();
if (setVal.getBool()) setValue(-1);
else if (clrVal.getBool()) setValue(0);
}
@Override
public void setInputs(ObservableValues inputs) throws BitsException {
super.setInputs(ovs(inputs.get(1), inputs.get(2)));
setVal = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
dVal = inputs.get(1).checkBits(bits, this, 1);
clockVal = inputs.get(2).addObserverToValue(this).checkBits(1, this, 2);
clrVal = inputs.get(3).addObserverToValue(this).checkBits(1, this, 3);
}
@Override
public ObservableValues getOutputs() {
return ovs(q, qn);
}
@Override
public void registerNodes(Model model) {
super.registerNodes(model);
if (isProbe)
model.addSignal(new Signal(label, q, v -> {
value = v;
q.setValue(value);
qn.setValue(~value);
}));
}
}

View File

@ -143,4 +143,7 @@ public class FlipflopJK extends Node implements Element {
}));
}
void setOut(boolean out) {
this.out = out;
}
}

View File

@ -1,7 +1,9 @@
package de.neemann.digital.core.flipflops;
import de.neemann.digital.core.*;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.BitsException;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
@ -14,7 +16,7 @@ import static de.neemann.digital.core.element.PinInfo.input;
*
* @author hneemann
*/
public class FlipflopJKAsync extends Node implements Element {
public class FlipflopJKAsync extends FlipflopJK {
/**
* The JK-FF description
@ -32,17 +34,8 @@ public class FlipflopJKAsync extends Node implements Element {
.addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final Boolean isProbe;
private final String label;
private ObservableValue setVal;
private ObservableValue clrVal;
private ObservableValue jVal;
private ObservableValue kVal;
private ObservableValue clockVal;
private ObservableValue q;
private ObservableValue qn;
private boolean lastClock;
private boolean out;
/**
* Creates a new instance
@ -50,64 +43,21 @@ public class FlipflopJKAsync extends Node implements Element {
* @param attributes the attributes
*/
public FlipflopJKAsync(ElementAttributes attributes) {
super(true);
this.q = new ObservableValue("Q", 1).setPinDescription(DESCRIPTION);
this.qn = new ObservableValue("\u00ACQ", 1).setPinDescription(DESCRIPTION);
isProbe = attributes.get(Keys.VALUE_IS_PROBE);
label = attributes.getCleanLabel();
int def = attributes.get(Keys.DEFAULT);
out = def > 0;
q.setBool(out);
qn.setBool(!out);
super(attributes);
}
@Override
public void readInputs() throws NodeException {
boolean clock = clockVal.getBool();
if (clock && !lastClock) {
boolean j = jVal.getBool();
boolean k = kVal.getBool();
if (j && k) out = !out;
else if (j) out = true;
else if (k) out = false;
}
lastClock = clock;
if (setVal.getBool()) out = true;
else if (clrVal.getBool()) out = false;
}
@Override
public void writeOutputs() throws NodeException {
q.setBool(out);
qn.setBool(!out);
super.readInputs();
if (setVal.getBool()) setOut(true);
else if (clrVal.getBool()) setOut(false);
}
@Override
public void setInputs(ObservableValues inputs) throws BitsException {
super.setInputs(ovs(inputs.get(1), inputs.get(2), inputs.get(3)));
setVal = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
jVal = inputs.get(1).checkBits(1, this, 1);
clockVal = inputs.get(2).addObserverToValue(this).checkBits(1, this, 2);
kVal = inputs.get(3).checkBits(1, this, 3);
clrVal = inputs.get(4).addObserverToValue(this).checkBits(1, this, 4);
}
@Override
public ObservableValues getOutputs() {
return ovs(q, qn);
}
@Override
public void registerNodes(Model model) {
super.registerNodes(model);
if (isProbe)
model.addSignal(new Signal(label, q, v -> {
out = v != 0;
q.setBool(out);
qn.setBool(!out);
}));
}
}