fets now have an option which makes them unidirectional

This commit is contained in:
hneemann 2017-06-23 17:33:47 +02:00
parent 26e3fe89af
commit 0c80f6684f
8 changed files with 203 additions and 117 deletions

View File

@ -384,4 +384,10 @@ public final class Keys {
public static final Key<Boolean> WITH_ENABLE
= new Key<>("withEnable", true);
/**
* true to simulate a unidirectional FET
*/
public static final Key<Boolean> FET_UNIDIRECTIONAL
= new Key<>("unidirectional", false);
}

View File

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

View File

@ -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);
/**

View File

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

View File

@ -671,6 +671,10 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
Angabe in Prozent der Standardgröße.</string>
<string name="key_withEnable">Enable Eingang</string>
<string name="key_withEnable_tt">Wenn gesetzt, ist ein Enable-Eingang (T) vorhanden.</string>
<string name="key_unidirectional">Unidirektional</string>
<string name="key_unidirectional_tt">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.</string>
<string name="mod_insertWire">Leitung eingefügt.</string>
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>

View File

@ -660,6 +660,10 @@ The names of the variables may not be unique.</string>
<string name="key_fontSize_tt">Size of the fonts used in the menu in percent of the default size.</string>
<string name="key_withEnable">Enable Input</string>
<string name="key_withEnable_tt">If set an enable input (T) is available.</string>
<string name="key_unidirectional">Unidirectional</string>
<string name="key_unidirectional_tt">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.</string>
<string name="mod_insertWire">Inserted wire.</string>
<string name="mod_insertCopied">Insert from clipboard.</string>

View File

@ -141,12 +141,22 @@ avoid the resistance problem
</visualElement>
<visualElement>
<elementName>NFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="860" y="400"/>
</visualElement>
<visualElement>
<elementName>NFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="860" y="460"/>
</visualElement>
<visualElement>
@ -156,22 +166,42 @@ avoid the resistance problem
</visualElement>
<visualElement>
<elementName>PFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1000" y="380"/>
</visualElement>
<visualElement>
<elementName>NFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1000" y="460"/>
</visualElement>
<visualElement>
<elementName>NFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1140" y="340"/>
</visualElement>
<visualElement>
<elementName>PFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1140" y="260"/>
</visualElement>
<visualElement>
@ -186,12 +216,22 @@ avoid the resistance problem
</visualElement>
<visualElement>
<elementName>NFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1140" y="560"/>
</visualElement>
<visualElement>
<elementName>PFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1140" y="480"/>
</visualElement>
<visualElement>
@ -205,32 +245,24 @@ avoid the resistance problem
<pos x="1020" y="360"/>
</visualElement>
<visualElement>
<elementName>DriverInvSel</elementName>
<elementName>PFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
<entry>
<string>flipSelPos</string>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="860" y="340"/>
<pos x="840" y="320"/>
</visualElement>
<visualElement>
<elementName>DriverInvSel</elementName>
<elementName>PFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
<entry>
<string>flipSelPos</string>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="920" y="340"/>
<pos x="900" y="320"/>
</visualElement>
</visualElements>
<wires>
@ -246,6 +278,14 @@ avoid the resistance problem
<p1 x="1080" y="320"/>
<p2 x="1100" y="320"/>
</wire>
<wire>
<p1 x="880" y="320"/>
<p2 x="900" y="320"/>
</wire>
<wire>
<p1 x="800" y="320"/>
<p2 x="840" y="320"/>
</wire>
<wire>
<p1 x="1100" y="320"/>
<p2 x="1120" y="320"/>
@ -254,6 +294,10 @@ avoid the resistance problem
<p1 x="1120" y="480"/>
<p2 x="1140" y="480"/>
</wire>
<wire>
<p1 x="960" y="240"/>
<p2 x="1160" y="240"/>
</wire>
<wire>
<p1 x="800" y="260"/>
<p2 x="920" y="260"/>
@ -262,26 +306,6 @@ avoid the resistance problem
<p1 x="1120" y="260"/>
<p2 x="1140" y="260"/>
</wire>
<wire>
<p1 x="1100" y="460"/>
<p2 x="1160" y="460"/>
</wire>
<wire>
<p1 x="780" y="620"/>
<p2 x="1160" y="620"/>
</wire>
<wire>
<p1 x="960" y="240"/>
<p2 x="1160" y="240"/>
</wire>
<wire>
<p1 x="800" y="340"/>
<p2 x="840" y="340"/>
</wire>
<wire>
<p1 x="880" y="340"/>
<p2 x="900" y="340"/>
</wire>
<wire>
<p1 x="780" y="500"/>
<p2 x="860" y="500"/>
@ -326,6 +350,14 @@ avoid the resistance problem
<p1 x="1120" y="600"/>
<p2 x="1140" y="600"/>
</wire>
<wire>
<p1 x="1100" y="460"/>
<p2 x="1160" y="460"/>
</wire>
<wire>
<p1 x="780" y="620"/>
<p2 x="1160" y="620"/>
</wire>
<wire>
<p1 x="980" y="380"/>
<p2 x="1000" y="380"/>
@ -360,15 +392,11 @@ avoid the resistance problem
</wire>
<wire>
<p1 x="800" y="320"/>
<p2 x="800" y="340"/>
</wire>
<wire>
<p1 x="800" y="340"/>
<p2 x="800" y="440"/>
</wire>
<wire>
<p1 x="880" y="280"/>
<p2 x="880" y="340"/>
<p2 x="880" y="320"/>
</wire>
<wire>
<p1 x="880" y="380"/>

View File

@ -33,7 +33,12 @@ avoid the resistance problem
</visualElement>
<visualElement>
<elementName>PFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="840" y="320"/>
</visualElement>
<visualElement>
@ -53,7 +58,12 @@ avoid the resistance problem
</visualElement>
<visualElement>
<elementName>PFET</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1080" y="380"/>
</visualElement>
<visualElement>
@ -190,55 +200,47 @@ avoid the resistance problem
<pos x="1100" y="300"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementName>NFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="900" y="420"/>
<pos x="880" y="400"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementName>NFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1140" y="480"/>
<pos x="1120" y="460"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementName>NFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="1060" y="480"/>
<pos x="1040" y="460"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementName>NFET</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
<string>unidirectional</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="820" y="420"/>
<pos x="800" y="400"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="1100" y="480"/>
<p2 x="1120" y="480"/>
</wire>
<wire>
<p1 x="1020" y="480"/>
<p2 x="1040" y="480"/>
</wire>
<wire>
<p1 x="780" y="480"/>
<p2 x="900" y="480"/>
@ -263,14 +265,6 @@ avoid the resistance problem
<p1 x="1020" y="640"/>
<p2 x="1100" y="640"/>
</wire>
<wire>
<p1 x="860" y="420"/>
<p2 x="880" y="420"/>
</wire>
<wire>
<p1 x="780" y="420"/>
<p2 x="800" y="420"/>
</wire>
<wire>
<p1 x="740" y="260"/>
<p2 x="760" y="260"/>
@ -311,6 +305,22 @@ avoid the resistance problem
<p1 x="760" y="720"/>
<p2 x="1140" y="720"/>
</wire>
<wire>
<p1 x="1100" y="500"/>
<p2 x="1120" y="500"/>
</wire>
<wire>
<p1 x="1020" y="500"/>
<p2 x="1040" y="500"/>
</wire>
<wire>
<p1 x="860" y="440"/>
<p2 x="880" y="440"/>
</wire>
<wire>
<p1 x="780" y="440"/>
<p2 x="800" y="440"/>
</wire>
<wire>
<p1 x="1060" y="440"/>
<p2 x="1100" y="440"/>
@ -428,7 +438,7 @@ avoid the resistance problem
<p2 x="1100" y="440"/>
</wire>
<wire>
<p1 x="1100" y="480"/>
<p1 x="1100" y="500"/>
<p2 x="1100" y="520"/>
</wire>
<wire>
@ -444,7 +454,7 @@ avoid the resistance problem
<p2 x="860" y="260"/>
</wire>
<wire>
<p1 x="860" y="420"/>
<p1 x="860" y="440"/>
<p2 x="860" y="460"/>
</wire>
<wire>
@ -453,22 +463,22 @@ avoid the resistance problem
</wire>
<wire>
<p1 x="780" y="320"/>
<p2 x="780" y="420"/>
<p2 x="780" y="440"/>
</wire>
<wire>
<p1 x="780" y="420"/>
<p1 x="780" y="440"/>
<p2 x="780" y="480"/>
</wire>
<wire>
<p1 x="1020" y="380"/>
<p2 x="1020" y="480"/>
<p2 x="1020" y="500"/>
</wire>
<wire>
<p1 x="1020" y="540"/>
<p2 x="1020" y="640"/>
</wire>
<wire>
<p1 x="1020" y="480"/>
<p1 x="1020" y="500"/>
<p2 x="1020" y="540"/>
</wire>
</wires>