From 0c80f6684f6b02596c9a275c828e4ce6633bf3f1 Mon Sep 17 00:00:00 2001 From: hneemann Date: Fri, 23 Jun 2017 17:33:47 +0200 Subject: [PATCH] fets now have an option which makes them unidirectional --- .../de/neemann/digital/core/element/Keys.java | 6 + .../neemann/digital/core/switching/NFET.java | 9 +- .../neemann/digital/core/switching/PFET.java | 1 + .../digital/core/switching/Switch.java | 84 ++++++++---- src/main/resources/lang/lang_de.xml | 4 + src/main/resources/lang/lang_en.xml | 4 + .../dig/test/fet/cmos10TFullAdder.dig | 122 +++++++++++------- .../dig/test/fet/cmosSERFFullAdder.dig | 90 +++++++------ 8 files changed, 203 insertions(+), 117 deletions(-) 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 ac2519e7d..5716b596b 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -384,4 +384,10 @@ public final class Keys { public static final Key WITH_ENABLE = new Key<>("withEnable", true); + /** + * true to simulate a unidirectional FET + */ + public static final Key FET_UNIDIRECTIONAL + = new Key<>("unidirectional", false); + } diff --git a/src/main/java/de/neemann/digital/core/switching/NFET.java b/src/main/java/de/neemann/digital/core/switching/NFET.java index 72dbadb41..41eaee492 100644 --- a/src/main/java/de/neemann/digital/core/switching/NFET.java +++ b/src/main/java/de/neemann/digital/core/switching/NFET.java @@ -20,6 +20,7 @@ public class NFET extends Node implements Element { public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(NFET.class, input("G")) .addAttribute(Keys.ROTATE) .addAttribute(Keys.BITS) + .addAttribute(Keys.FET_UNIDIRECTIONAL) .addAttribute(Keys.LABEL); private final Switch s; @@ -38,10 +39,14 @@ public class NFET extends Node implements Element { } NFET(ElementAttributes attr, boolean pChan) { - if (pChan) + boolean uniDir = attr.get(Keys.FET_UNIDIRECTIONAL); + if (pChan) { s = new Switch(attr, false, "S", "D"); - else + if (uniDir) s.setUnidirectional(Switch.Unidirectional.FROM1TO2); + } else { s = new Switch(attr, false, "D", "S"); + if (uniDir) s.setUnidirectional(Switch.Unidirectional.FROM2TO1); + } } @Override diff --git a/src/main/java/de/neemann/digital/core/switching/PFET.java b/src/main/java/de/neemann/digital/core/switching/PFET.java index 0c62c2089..064962a45 100644 --- a/src/main/java/de/neemann/digital/core/switching/PFET.java +++ b/src/main/java/de/neemann/digital/core/switching/PFET.java @@ -18,6 +18,7 @@ public class PFET extends NFET { public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(PFET.class, input("G")) .addAttribute(Keys.ROTATE) .addAttribute(Keys.BITS) + .addAttribute(Keys.FET_UNIDIRECTIONAL) .addAttribute(Keys.LABEL); /** diff --git a/src/main/java/de/neemann/digital/core/switching/Switch.java b/src/main/java/de/neemann/digital/core/switching/Switch.java index 8fe81a74d..5f3002cb2 100644 --- a/src/main/java/de/neemann/digital/core/switching/Switch.java +++ b/src/main/java/de/neemann/digital/core/switching/Switch.java @@ -17,6 +17,11 @@ import org.slf4j.LoggerFactory; public class Switch implements Element, NodeInterface { private static final Logger LOGGER = LoggerFactory.getLogger(Switch.class); + /** + * Defines a direction for the switch. NO means no direction is given, the switch is bidirectional. + */ + public enum Unidirectional {NO, FROM1TO2, FROM2TO1} + /** * The switch description */ @@ -31,10 +36,12 @@ public class Switch implements Element, NodeInterface { private final int bits; private boolean closed; private SwitchModel switchModel; + private Unidirectional unidirectional = Unidirectional.NO; private static int debugSwitchReal; private static int debugSwitchSimple; + /** * Creates a new instance * @@ -46,6 +53,17 @@ public class Switch implements Element, NodeInterface { output2.setPinDescription(DESCRIPTION); } + /** + * Sets this switch to unidirectional + * + * @param unidirectional the state + * @return this for chained calls + */ + public Switch setUnidirectional(Unidirectional unidirectional) { + this.unidirectional = unidirectional; + return this; + } + /** * Creates a new instance * @@ -65,40 +83,50 @@ public class Switch implements Element, NodeInterface { public void setInputs(ObservableValues inputs) throws NodeException { ObservableValue input1 = inputs.get(0).addObserverToValue(this).checkBits(bits, null); ObservableValue input2 = inputs.get(1).addObserverToValue(this).checkBits(bits, null); - if (input1 instanceof CommonBusValue) { - if (input2 instanceof CommonBusValue) { - 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 { - // not a constant - boolean def1 = in1.isAlwaysDefined(); - boolean def2 = in2.isAlwaysDefined(); - if (def1 == def2) - switchModel = new RealSwitch(in1, in2); + switch (unidirectional) { + case NO: + if (input1 instanceof CommonBusValue) { + if (input2 instanceof CommonBusValue) { + final CommonBusValue in1 = (CommonBusValue) input1; + final CommonBusValue in2 = (CommonBusValue) input2; + ObservableValue constant = in1.searchConstant(); + if (constant != null) + switchModel = new SimpleSwitch(constant, output2); else { - if (def1) - switchModel = new SimpleSwitch(input1, output2); - else - switchModel = new SimpleSwitch(input2, output1); + constant = in2.searchConstant(); + if (constant != null) + switchModel = new SimpleSwitch(constant, output1); + else { + // not a constant + boolean def1 = in1.isAlwaysDefined(); + boolean def2 = in2.isAlwaysDefined(); + if (def1 == def2) + switchModel = new RealSwitch(in1, in2); + else { + if (def1) + switchModel = new SimpleSwitch(input1, output2); + else + switchModel = new SimpleSwitch(input2, output1); + } + } } + } else { + switchModel = new SimpleSwitch(input1, output2); + } + } else { + if (input2 instanceof CommonBusValue) { + switchModel = new SimpleSwitch(input2, output1); + } else { + throw new NodeException(Lang.get("err_switchHasNoNet"), output1, output2); } } - } else { + break; + case FROM1TO2: switchModel = new SimpleSwitch(input1, output2); - } - } else { - if (input2 instanceof CommonBusValue) { + break; + case FROM2TO1: switchModel = new SimpleSwitch(input2, output1); - } else { - throw new NodeException(Lang.get("err_switchHasNoNet"), output1, output2); - } + break; } if (switchModel instanceof RealSwitch) debugSwitchReal++; diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 36e252c3d..7de70694f 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -671,6 +671,10 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Angabe in Prozent der Standardgröße. Enable Eingang Wenn gesetzt, ist ein Enable-Eingang (T) vorhanden. + Unidirektional + Unidirektionale Transitoren wirken nur von Source zu Drain. Sie können deutlich + schneller simuliert werden, als bidirektionale Transistoren. Es gibt jedoch keine Rückwirkung von Drain zu Source was + unter Umständen zu Problemen führt. 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 3a7136383..f4b1c707e 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -660,6 +660,10 @@ The names of the variables may not be unique. Size of the fonts used in the menu in percent of the default size. Enable Input If set an enable input (T) is available. + Unidirectional + Unidirectional transistors propagate a signal only from source to drain. They are + much faster to simulate than bidirectional transistors. But there is no feedback from drain to source which may + cause issues. Inserted wire. Insert from clipboard. diff --git a/src/test/resources/dig/test/fet/cmos10TFullAdder.dig b/src/test/resources/dig/test/fet/cmos10TFullAdder.dig index 0c63bfaef..a3c0a4ae2 100644 --- a/src/test/resources/dig/test/fet/cmos10TFullAdder.dig +++ b/src/test/resources/dig/test/fet/cmos10TFullAdder.dig @@ -141,12 +141,22 @@ avoid the resistance problem NFET - + + + unidirectional + true + + NFET - + + + unidirectional + true + + @@ -156,22 +166,42 @@ avoid the resistance problem PFET - + + + unidirectional + true + + NFET - + + + unidirectional + true + + NFET - + + + unidirectional + true + + PFET - + + + unidirectional + true + + @@ -186,12 +216,22 @@ avoid the resistance problem NFET - + + + unidirectional + true + + PFET - + + + unidirectional + true + + @@ -205,32 +245,24 @@ avoid the resistance problem - DriverInvSel + PFET - rotation - - - - flipSelPos + unidirectional true - + - DriverInvSel + PFET - rotation - - - - flipSelPos + unidirectional true - + @@ -246,6 +278,14 @@ avoid the resistance problem + + + + + + + + @@ -254,6 +294,10 @@ avoid the resistance problem + + + + @@ -262,26 +306,6 @@ avoid the resistance problem - - - - - - - - - - - - - - - - - - - - @@ -326,6 +350,14 @@ avoid the resistance problem + + + + + + + + @@ -360,15 +392,11 @@ avoid the resistance problem - - - - - + diff --git a/src/test/resources/dig/test/fet/cmosSERFFullAdder.dig b/src/test/resources/dig/test/fet/cmosSERFFullAdder.dig index 84e6d5485..cc9013f23 100644 --- a/src/test/resources/dig/test/fet/cmosSERFFullAdder.dig +++ b/src/test/resources/dig/test/fet/cmosSERFFullAdder.dig @@ -33,7 +33,12 @@ avoid the resistance problem PFET - + + + unidirectional + true + + @@ -53,7 +58,12 @@ avoid the resistance problem PFET - + + + unidirectional + true + + @@ -190,55 +200,47 @@ avoid the resistance problem - Driver + NFET - rotation - + unidirectional + true - + - Driver + NFET - rotation - + unidirectional + true - + - Driver + NFET - rotation - + unidirectional + true - + - Driver + NFET - rotation - + unidirectional + true - + - - - - - - - - @@ -263,14 +265,6 @@ avoid the resistance problem - - - - - - - - @@ -311,6 +305,22 @@ avoid the resistance problem + + + + + + + + + + + + + + + + @@ -428,7 +438,7 @@ avoid the resistance problem - + @@ -444,7 +454,7 @@ avoid the resistance problem - + @@ -453,22 +463,22 @@ avoid the resistance problem - + - + - + - +