diff --git a/src/main/dig/processor/core/ClockDiv.dig b/src/main/dig/processor/core/ClockDiv.dig
index e9e3e6bb1..265eea44b 100644
--- a/src/main/dig/processor/core/ClockDiv.dig
+++ b/src/main/dig/processor/core/ClockDiv.dig
@@ -28,7 +28,12 @@ dann ausgeführt.
T_FF
-
+
+
+ withEnable
+ false
+
+
diff --git a/src/main/dig/sequential/Counter-T.dig b/src/main/dig/sequential/Counter-T.dig
index 8e7e2cbc2..035aef702 100644
--- a/src/main/dig/sequential/Counter-T.dig
+++ b/src/main/dig/sequential/Counter-T.dig
@@ -1,6 +1,7 @@
1
+
Out
@@ -11,7 +12,6 @@
- 3
Clock
@@ -26,7 +26,6 @@
- 0
Out
@@ -37,7 +36,6 @@
- 3
Out
@@ -48,7 +46,6 @@
- 3
Out
@@ -59,7 +56,6 @@
- 3
T_FF
@@ -68,13 +64,16 @@
valueIsProbe
true
+
+ withEnable
+ false
+
Label
Q_0
- 0
T_FF
@@ -83,13 +82,22 @@
valueIsProbe
true
+
+ withEnable
+ false
+
Label
Q_1
+
+ inverterConfig
+
+ C
+
+
- 0
T_FF
@@ -98,13 +106,22 @@
valueIsProbe
true
+
+ withEnable
+ false
+
Label
Q_2
+
+ inverterConfig
+
+ C
+
+
- 0
T_FF
@@ -113,13 +130,22 @@
valueIsProbe
true
+
+ withEnable
+ false
+
Label
Q_3
+
+ inverterConfig
+
+ C
+
+
- 0
Data
@@ -138,7 +164,6 @@
- 0
Text
@@ -149,7 +174,6 @@
- 0
@@ -158,44 +182,32 @@
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
-
+
+
@@ -213,17 +225,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/dig/sequential/Prescaler.dig b/src/main/dig/sequential/Prescaler.dig
index f97e449ad..80990d975 100644
--- a/src/main/dig/sequential/Prescaler.dig
+++ b/src/main/dig/sequential/Prescaler.dig
@@ -25,22 +25,42 @@ Teilerverhältnisse 1/2, 1/4, 1/8 und 1/16.
T_FF
-
+
+
+ withEnable
+ false
+
+
T_FF
-
+
+
+ withEnable
+ false
+
+
T_FF
-
+
+
+ withEnable
+ false
+
+
T_FF
-
+
+
+ withEnable
+ false
+
+
diff --git a/src/main/java/de/neemann/digital/analyse/ModelAnalyser.java b/src/main/java/de/neemann/digital/analyse/ModelAnalyser.java
index bfbe820e7..bf88f8434 100644
--- a/src/main/java/de/neemann/digital/analyse/ModelAnalyser.java
+++ b/src/main/java/de/neemann/digital/analyse/ModelAnalyser.java
@@ -46,8 +46,8 @@ public class ModelAnalyser {
this.model = model;
try {
- replaceJKFF();
replaceTFF();
+ replaceJKFF();
} catch (NodeException e) {
throw new AnalyseException(e);
}
diff --git a/src/main/java/de/neemann/digital/core/basic/FanIn.java b/src/main/java/de/neemann/digital/core/basic/FanIn.java
index a93a04514..b124c3e8b 100644
--- a/src/main/java/de/neemann/digital/core/basic/FanIn.java
+++ b/src/main/java/de/neemann/digital/core/basic/FanIn.java
@@ -76,7 +76,7 @@ public abstract class FanIn extends Node implements Element {
addAttribute(Keys.ROTATE);
addAttribute(Keys.BITS);
addAttribute(Keys.INPUT_COUNT);
- addAttribute(Keys.INVERTERCONFIG);
+ addAttribute(Keys.INVERTER_CONFIG);
}
@Override
diff --git a/src/main/java/de/neemann/digital/core/basic/XNOr.java b/src/main/java/de/neemann/digital/core/basic/XNOr.java
index 6307c084d..ade2e9eef 100644
--- a/src/main/java/de/neemann/digital/core/basic/XNOr.java
+++ b/src/main/java/de/neemann/digital/core/basic/XNOr.java
@@ -20,7 +20,7 @@ public class XNOr extends XOr {
= new ElementTypeDescription(XNOr.class, input("a"), input("b"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
- .addAttribute(Keys.INVERTERCONFIG);
+ .addAttribute(Keys.INVERTER_CONFIG);
/**
* Creates a new instance
diff --git a/src/main/java/de/neemann/digital/core/basic/XOr.java b/src/main/java/de/neemann/digital/core/basic/XOr.java
index 9649af0da..06b5e7593 100644
--- a/src/main/java/de/neemann/digital/core/basic/XOr.java
+++ b/src/main/java/de/neemann/digital/core/basic/XOr.java
@@ -20,7 +20,7 @@ public class XOr extends Node implements Element {
= new ElementTypeDescription(XOr.class, input("a"), input("b"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
- .addAttribute(Keys.INVERTERCONFIG);
+ .addAttribute(Keys.INVERTER_CONFIG);
private final int bits;
private final ObservableValue out;
diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java
index 3d036b9b7..ac2519e7d 100644
--- a/src/main/java/de/neemann/digital/core/element/Keys.java
+++ b/src/main/java/de/neemann/digital/core/element/Keys.java
@@ -277,7 +277,7 @@ public final class Keys {
/**
* output format for numbers
*/
- public static final Key.KeyEnum INTFORMAT
+ public static final Key.KeyEnum INT_FORMAT
= new Key.KeyEnum<>("intFormat", IntFormat.def, IntFormat.values());
/**
@@ -365,7 +365,7 @@ public final class Keys {
/**
* contains the input inverter config
*/
- public static final Key INVERTERCONFIG
+ public static final Key INVERTER_CONFIG
= new Key<>("inverterConfig", new InverterConfig());
@@ -378,4 +378,10 @@ public final class Keys {
.setMin(50)
.setMax(400);
+ /**
+ * true if a enable input is needed
+ */
+ public static final Key WITH_ENABLE
+ = new Key<>("withEnable", true);
+
}
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java
index 7ad75a06c..296436e84 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java
@@ -25,7 +25,7 @@ public class FlipflopD extends Node implements Element {
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final int bits;
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopDAsync.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopDAsync.java
index 519c309c8..95dd9f2cd 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopDAsync.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopDAsync.java
@@ -25,7 +25,7 @@ public class FlipflopDAsync extends Node implements Element {
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final int bits;
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopJK.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopJK.java
index 9a9d2ae8b..a8d88854e 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopJK.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopJK.java
@@ -24,7 +24,7 @@ public class FlipflopJK extends Node implements Element {
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final Boolean isProbe;
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopJKAsync.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopJKAsync.java
index 9036abbb6..36c794622 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopJKAsync.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopJKAsync.java
@@ -29,7 +29,7 @@ public class FlipflopJKAsync extends Node implements Element {
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final Boolean isProbe;
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopRS.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopRS.java
index 7bceaa0c1..06ea3f690 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopRS.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopRS.java
@@ -24,7 +24,7 @@ public class FlipflopRS extends Node implements Element {
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final boolean isProbe;
diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopT.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopT.java
index a47dc8c97..1e18b466b 100644
--- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopT.java
+++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopT.java
@@ -1,10 +1,7 @@
package de.neemann.digital.core.flipflops;
import de.neemann.digital.core.*;
-import de.neemann.digital.core.element.Element;
-import de.neemann.digital.core.element.ElementAttributes;
-import de.neemann.digital.core.element.ElementTypeDescription;
-import de.neemann.digital.core.element.Keys;
+import de.neemann.digital.core.element.*;
import static de.neemann.digital.core.ObservableValues.ovs;
import static de.neemann.digital.core.element.PinInfo.input;
@@ -20,17 +17,28 @@ public class FlipflopT extends Node implements Element {
* The T-FF description
*/
public static final ElementTypeDescription DESCRIPTION
- = new ElementTypeDescription("T_FF", FlipflopT.class, input("C"))
+ = new ElementTypeDescription("T_FF", FlipflopT.class) {
+ @Override
+ public PinDescriptions getInputDescription(ElementAttributes elementAttributes) throws NodeException {
+ if (elementAttributes.get(Keys.WITH_ENABLE))
+ return new PinDescriptions(input("T"), input("C")).setLangKey(getPinLangKey());
+ else
+ return new PinDescriptions(input("C")).setLangKey(getPinLangKey());
+ }
+ }
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
+ .addAttribute(Keys.WITH_ENABLE)
.addAttribute(Keys.DEFAULT)
- .addAttribute(Keys.INVERTERCONFIG)
+ .addAttribute(Keys.INVERTER_CONFIG)
.addAttribute(Keys.VALUE_IS_PROBE);
private final boolean isProbe;
private final String label;
+ private final boolean isEnable;
private ObservableValue clockVal;
+ private ObservableValue enable;
private ObservableValue q;
private ObservableValue qn;
private boolean lastClock;
@@ -45,6 +53,7 @@ public class FlipflopT extends Node implements Element {
super(true);
this.q = new ObservableValue("Q", 1).setPinDescription(DESCRIPTION);
this.qn = new ObservableValue("\u00ACQ", 1).setPinDescription(DESCRIPTION);
+ isEnable = attributes.get(Keys.WITH_ENABLE);
isProbe = attributes.get(Keys.VALUE_IS_PROBE);
label = attributes.getCleanLabel();
@@ -58,7 +67,12 @@ public class FlipflopT extends Node implements Element {
public void readInputs() throws NodeException {
boolean clock = clockVal.getBool();
if (clock && !lastClock) {
- out = !out;
+ if (enable == null)
+ out = !out;
+ else {
+ if (enable.getBool())
+ out = !out;
+ }
}
lastClock = clock;
}
@@ -71,7 +85,11 @@ public class FlipflopT extends Node implements Element {
@Override
public void setInputs(ObservableValues inputs) throws BitsException {
- clockVal = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
+ if (isEnable) {
+ enable = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
+ clockVal = inputs.get(1).addObserverToValue(this).checkBits(1, this, 1);
+ } else
+ clockVal = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
}
@Override
diff --git a/src/main/java/de/neemann/digital/core/io/Probe.java b/src/main/java/de/neemann/digital/core/io/Probe.java
index c58618066..7ed822203 100644
--- a/src/main/java/de/neemann/digital/core/io/Probe.java
+++ b/src/main/java/de/neemann/digital/core/io/Probe.java
@@ -22,7 +22,7 @@ public class Probe implements Element {
= new ElementTypeDescription("Probe", Probe.class, input("in"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
- .addAttribute(Keys.INTFORMAT);
+ .addAttribute(Keys.INT_FORMAT);
private final String label;
private ObservableValue value;
diff --git a/src/main/java/de/neemann/digital/draw/model/ModelEntry.java b/src/main/java/de/neemann/digital/draw/model/ModelEntry.java
index a40529902..2fd6d5565 100644
--- a/src/main/java/de/neemann/digital/draw/model/ModelEntry.java
+++ b/src/main/java/de/neemann/digital/draw/model/ModelEntry.java
@@ -60,7 +60,7 @@ public class ModelEntry {
try {
HashMap ins = pins.getInputs();
- InverterConfig ic = visualElement.getElementAttributes().get(Keys.INVERTERCONFIG);
+ InverterConfig ic = visualElement.getElementAttributes().get(Keys.INVERTER_CONFIG);
ObservableValues values = ObservableValues.EMPTY_LIST;
ArrayList inputs = new ArrayList<>();
diff --git a/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java b/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java
index 11be7633c..9e86b99a5 100644
--- a/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java
+++ b/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java
@@ -41,7 +41,7 @@ public class ProbeShape implements Shape {
if (label == null || label.length() == 0)
label = Lang.get("name");
this.label = label;
- this.format = attr.get(Keys.INTFORMAT);
+ this.format = attr.get(Keys.INT_FORMAT);
}
@Override
diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
index ea8368179..aac5acd2d 100644
--- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
+++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
@@ -166,7 +166,7 @@ public final class ShapeFactory {
pt.getOutputDescriptions(elementAttributes),
elementAttributes.getLabel(),
true)
- .setInverterConfig(elementAttributes.get(Keys.INVERTERCONFIG));
+ .setInverterConfig(elementAttributes.get(Keys.INVERTER_CONFIG));
}
}
} else {
@@ -200,7 +200,7 @@ public final class ShapeFactory {
public Shape create(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) throws NodeException {
return new GenericShape(name, inputs, outputs)
.invert(invers)
- .setInverterConfig(attributes.get(Keys.INVERTERCONFIG));
+ .setInverterConfig(attributes.get(Keys.INVERTER_CONFIG));
}
}
}
diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java
index dbd3515d5..abbb4ba7e 100644
--- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java
+++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java
@@ -44,7 +44,7 @@ public abstract class IEEEGenericShape implements Shape {
this.inputs = inputs;
this.outputs = outputs;
this.invert = invert;
- inverterConfig = attr.get(Keys.INVERTERCONFIG);
+ inverterConfig = attr.get(Keys.INVERTER_CONFIG);
}
@Override
diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml
index 3a30d54ac..36e252c3d 100644
--- a/src/main/resources/lang/lang_de.xml
+++ b/src/main/resources/lang/lang_de.xml
@@ -331,8 +331,9 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.Ausgang gibt 1 aus wenn bei der Substraktion ein Überlauf aufgetreten ist.
T-FlipFlop
T
- Wechselt den Status der Ausgänge mit jeder 1 am Eingang.
- Dieser Eingang nimmt ein Bit entgegen und wechselt jedes mal die Ausgänge wenn er auf 1 gesetzt wird (toggle).
+ Speichert ein Bit welches sich mit einem Eingang umschalten lässt.
+ Aktiviert die Umschaltfunktion.
+ Dieser Eingang schaltet das Flipflop um. Wenn ein T-Eingang vorhanden ist passiert das nur, wenn T auf 1 gesetzt ist.
Gibt den gespeicherten Wert aus.
Gibt den gespeicherten Wert negiert aus.
Terminal
@@ -668,6 +669,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?
Schriftgröße im Menü [%]
Für die Menüs kann eine abweichende Schriftgröße gewählt werden.
Angabe in Prozent der Standardgröße.
+ Enable Eingang
+ Wenn gesetzt, ist ein Enable-Eingang (T) vorhanden.
Leitung eingefügt.
Aus Zwischenablage eingefügt.
diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml
index 7fd95c3ca..3a7136383 100644
--- a/src/main/resources/lang/lang_en.xml
+++ b/src/main/resources/lang/lang_en.xml
@@ -325,8 +325,9 @@
Output returns 1 if an overflow occurred.
T-FlipFlop
T
- A component with one input. Toggles the state of the output on a rising edge at the input.
- Clock. A rising edge toggles the output.
+ Stores a single bit. Toggles the state on a rising edge at input C.
+ Enables the toggle function.
+ Clock. A rising edge toggles the output, if input T is set to 1.
Returns the stored value.
Returns the negated stored value.
Terminal
@@ -657,6 +658,8 @@ The names of the variables may not be unique.
You can select the inputs that are to be inverted.
Menus Font Size [%]
Size of the fonts used in the menu in percent of the default size.
+ Enable Input
+ If set an enable input (T) is available.
Inserted wire.
Insert from clipboard.
diff --git a/src/test/java/de/neemann/digital/core/flipflops/FlipflopT_Test.java b/src/test/java/de/neemann/digital/core/flipflops/FlipflopT_Test.java
index fd05d8842..ef610e33e 100644
--- a/src/test/java/de/neemann/digital/core/flipflops/FlipflopT_Test.java
+++ b/src/test/java/de/neemann/digital/core/flipflops/FlipflopT_Test.java
@@ -3,18 +3,21 @@ package de.neemann.digital.core.flipflops;
import de.neemann.digital.TestExecuter;
import de.neemann.digital.core.Model;
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.Keys;
import junit.framework.TestCase;
/**
* @author hneemann
*/
public class FlipflopT_Test extends TestCase {
+
public void testFlipFlop() throws Exception {
ObservableValue c = new ObservableValue("c", 1);
Model model = new Model();
- FlipflopT out = model.add(new FlipflopT(new ElementAttributes().setBits(1)));
+ FlipflopT out = model.add(new FlipflopT(new ElementAttributes().setBits(1).set(Keys.WITH_ENABLE, false)));
out.setInputs(c.asList());
TestExecuter sc = new TestExecuter(model).setInputs(c).setOutputs(out.getOutputs());
@@ -27,4 +30,32 @@ public class FlipflopT_Test extends TestCase {
sc.check(1, 0, 1);
sc.check(0, 0, 1);
}
+
+ public void testFlipFlopWithEnable() throws Exception {
+ ObservableValue t = new ObservableValue("t", 1);
+ ObservableValue c = new ObservableValue("c", 1);
+
+ Model model = new Model();
+ FlipflopT out = model.add(new FlipflopT(new ElementAttributes().setBits(1).set(Keys.WITH_ENABLE, true)));
+ out.setInputs(new ObservableValues(t, c));
+
+ TestExecuter sc = new TestExecuter(model).setInputs(t, c).setOutputs(out.getOutputs());
+ // T C Q ~Q
+ sc.check(1, 0, 0, 1);
+ sc.check(1, 1, 1, 0);
+ sc.check(1, 1, 1, 0);
+ sc.check(1, 0, 1, 0);
+ sc.check(1, 0, 1, 0);
+ sc.check(1, 1, 0, 1);
+ sc.check(1, 0, 0, 1);
+ sc.check(0, 1, 0, 1);
+ sc.check(0, 0, 0, 1);
+ sc.check(0, 1, 0, 1);
+ sc.check(0, 0, 0, 1);
+ sc.check(1, 1, 1, 0);
+ sc.check(0, 0, 1, 0);
+ sc.check(0, 1, 1, 0);
+ sc.check(0, 0, 1, 0);
+ }
+
}
\ No newline at end of file