Added a floating gate N channel fet

This commit is contained in:
hneemann 2017-04-15 15:42:51 +02:00
parent 46e8891d26
commit e82e59a67d
13 changed files with 6064 additions and 42 deletions

View File

@ -0,0 +1,45 @@
package de.neemann.digital.core.switching;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import static de.neemann.digital.core.element.PinInfo.input;
/**
* P-Channel MOS FET
* Created by hneemann on 22.02.17.
*/
public class FGNFET extends NFET {
/**
* The switch description
*/
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(FGNFET.class, input("G"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.BLOWN);
private final boolean programmed;
/**
* Create a new instance
*
* @param attr the attributes
*/
public FGNFET(ElementAttributes attr) {
super(attr);
getOutput1().setPinDescription(DESCRIPTION);
getOutput2().setPinDescription(DESCRIPTION);
programmed = attr.get(Keys.BLOWN);
}
@Override
boolean getClosed(ObservableValue input) {
if (input.isHighZ() || programmed)
return false;
else
return input.getBool();
}
}

View File

@ -25,7 +25,6 @@ public class NFET extends Node implements Element {
private final Switch s;
private ObservableValue input;
private boolean closed;
private boolean invert;
/**
* Create a new instance
@ -33,18 +32,7 @@ public class NFET extends Node implements Element {
* @param attr the attributes
*/
public NFET(ElementAttributes attr) {
this(attr, false);
}
/**
* Create a new instance
*
* @param attr the attributes
* @param invert invert the input
*/
protected NFET(ElementAttributes attr, boolean invert) {
s = new Switch(attr, false);
this.invert = invert;
s.getOutput1().setPinDescription(DESCRIPTION);
s.getOutput2().setPinDescription(DESCRIPTION);
}
@ -63,10 +51,20 @@ public class NFET extends Node implements Element {
@Override
public void readInputs() throws NodeException {
closed = getClosed(input);
}
/**
* Determines the state of the FET debending on its input
*
* @param input the input
* @return true if FET is conducting
*/
boolean getClosed(ObservableValue input) {
if (input.isHighZ())
closed = false;
return false;
else
closed = input.getBool() ^ invert;
return input.getBool();
}
@Override
@ -89,14 +87,14 @@ public class NFET extends Node implements Element {
/**
* @return output 1
*/
public ObservableValue getOutput1() {
ObservableValue getOutput1() {
return s.getOutput1();
}
/**
* @return output 2
*/
public ObservableValue getOutput2() {
ObservableValue getOutput2() {
return s.getOutput2();
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.core.switching;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
@ -25,8 +26,17 @@ public class PFET extends NFET {
* @param attr the attributes
*/
public PFET(ElementAttributes attr) {
super(attr, true);
super(attr);
getOutput1().setPinDescription(DESCRIPTION);
getOutput2().setPinDescription(DESCRIPTION);
}
@Override
boolean getClosed(ObservableValue input) {
if (input.isHighZ())
return false;
else
return !input.getBool();
}
}

View File

@ -15,6 +15,7 @@ import de.neemann.digital.core.memory.DataFieldConverter;
import de.neemann.digital.core.pld.Diode;
import de.neemann.digital.core.pld.DiodeBackward;
import de.neemann.digital.core.pld.DiodeForeward;
import de.neemann.digital.core.switching.FGNFET;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
@ -614,7 +615,8 @@ public class Circuit {
for (VisualElement ve : visualElements)
if (ve.equalsDescription(DiodeForeward.DESCRIPTION)
|| ve.equalsDescription(DiodeBackward.DESCRIPTION)
|| ve.equalsDescription(Diode.DESCRIPTION)) {
|| ve.equalsDescription(Diode.DESCRIPTION)
|| ve.equalsDescription(FGNFET.DESCRIPTION)) {
ve.getElementAttributes().set(Keys.BLOWN, false);
modified = true;
}

View File

@ -13,10 +13,7 @@ import de.neemann.digital.core.pld.DiodeBackward;
import de.neemann.digital.core.pld.DiodeForeward;
import de.neemann.digital.core.pld.PullDown;
import de.neemann.digital.core.pld.PullUp;
import de.neemann.digital.core.switching.NFET;
import de.neemann.digital.core.switching.PFET;
import de.neemann.digital.core.switching.Relay;
import de.neemann.digital.core.switching.Switch;
import de.neemann.digital.core.switching.*;
import de.neemann.digital.core.wiring.*;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
@ -133,6 +130,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
.add(Relay.DESCRIPTION)
.add(NFET.DESCRIPTION)
.add(PFET.DESCRIPTION)
.add(FGNFET.DESCRIPTION)
.add(Reset.DESCRIPTION)
.add(Break.DESCRIPTION))
.add(new LibraryNode(Lang.get("lib_test"))

View File

@ -18,6 +18,7 @@ public abstract class FETShape implements Shape {
private final PinDescriptions inputs;
private final PinDescriptions outputs;
private final String label;
private int xOffs = SIZE2 - 2;
private NFET fet;
/**
@ -27,12 +28,21 @@ public abstract class FETShape implements Shape {
* @param inputs the inputs
* @param outputs the outputs
*/
protected FETShape(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) {
FETShape(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) {
this.inputs = inputs;
this.outputs = outputs;
label = attributes.getCleanLabel();
}
/**
* Sets the gap width
*
* @param xOffs the gap width
*/
void setXOffs(int xOffs) {
this.xOffs = xOffs;
}
@Override
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
fet = (NFET) ioState.getElement();
@ -42,19 +52,18 @@ public abstract class FETShape implements Shape {
@Override
public void drawTo(Graphic graphic, boolean highLight) {
final int x1 = SIZE2 - 2;
final int g = SIZE2 / 2;
graphic.drawPolygon(new Polygon(false)
.add(SIZE, 0)
.add(x1, 0)
.add(x1, SIZE2 - g), Style.NORMAL);
.add(xOffs, 0)
.add(xOffs, SIZE2 - g), Style.NORMAL);
graphic.drawPolygon(new Polygon(false)
.add(SIZE, SIZE * 2)
.add(x1, SIZE * 2)
.add(x1, SIZE * 2 - SIZE2 + g), Style.NORMAL);
.add(xOffs, SIZE * 2)
.add(xOffs, SIZE * 2 - SIZE2 + g), Style.NORMAL);
graphic.drawLine(new Vector(x1, SIZE2 + g), new Vector(x1, SIZE + SIZE2 - g), Style.NORMAL);
graphic.drawLine(new Vector(xOffs, SIZE2 + g), new Vector(xOffs, SIZE + SIZE2 - g), Style.NORMAL);
graphic.drawLine(new Vector(1, 0), new Vector(1, SIZE * 2), Style.NORMAL);

View File

@ -0,0 +1,60 @@
package de.neemann.digital.draw.shapes;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.Pins;
import de.neemann.digital.draw.graphics.Graphic;
import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
/**
* The n-chan FET shape
*/
public class FGFETShapeN extends FETShape {
private final boolean programmed;
/**
* Creates a new instance
*
* @param attributes the attributes
* @param inputs the inputs
* @param outputs the outputs
*/
public FGFETShapeN(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) {
super(attributes, inputs, outputs);
programmed = attributes.get(Keys.BLOWN);
setXOffs(SIZE2 + 1);
}
@Override
public Pins getPins() {
return new Pins()
.add(new Pin(new Vector(0, SIZE * 2), getInputs().get(0)))
.add(new Pin(new Vector(SIZE, 0), getOutputs().get(0)))
.add(new Pin(new Vector(SIZE, SIZE * 2), getOutputs().get(1)));
}
@Override
public void drawTo(Graphic graphic, boolean highLight) {
super.drawTo(graphic, highLight);
if (programmed)
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), Style.HIGHLIGHT);
else
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), Style.THIN);
// the arrow
graphic.drawLine(new Vector(SIZE2 + 5, SIZE), new Vector(SIZE, SIZE), Style.THIN);
graphic.drawPolygon(new Polygon(true)
.add(SIZE2 + 2, SIZE)
.add(SIZE - SIZE2 / 3, SIZE - SIZE2 / 4)
.add(SIZE - SIZE2 / 3, SIZE + SIZE2 / 4), Style.THIN_FILLED);
}
}

View File

@ -11,10 +11,7 @@ import de.neemann.digital.core.memory.RAMDualPort;
import de.neemann.digital.core.memory.RAMSinglePort;
import de.neemann.digital.core.memory.RAMSinglePortSel;
import de.neemann.digital.core.pld.*;
import de.neemann.digital.core.switching.NFET;
import de.neemann.digital.core.switching.PFET;
import de.neemann.digital.core.switching.Relay;
import de.neemann.digital.core.switching.Switch;
import de.neemann.digital.core.switching.*;
import de.neemann.digital.core.wiring.*;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.Tunnel;
@ -88,6 +85,7 @@ public final class ShapeFactory {
map.put(Switch.DESCRIPTION.getName(), SwitchShape::new);
map.put(Relay.DESCRIPTION.getName(), RelayShape::new);
map.put(NFET.DESCRIPTION.getName(), FETShapeN::new);
map.put(FGNFET.DESCRIPTION.getName(), FGFETShapeN::new);
map.put(PFET.DESCRIPTION.getName(), FETShapeP::new);
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);

View File

@ -10,6 +10,7 @@ import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.pld.Diode;
import de.neemann.digital.core.pld.DiodeBackward;
import de.neemann.digital.core.pld.DiodeForeward;
import de.neemann.digital.core.switching.FGNFET;
import de.neemann.digital.draw.elements.*;
import de.neemann.digital.draw.graphics.*;
import de.neemann.digital.draw.library.ElementLibrary;
@ -236,7 +237,8 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
VisualElement ve = circuit.getElementAt(pos);
if (ve != null && (ve.equalsDescription(DiodeBackward.DESCRIPTION)
|| ve.equalsDescription(DiodeForeward.DESCRIPTION)
|| ve.equalsDescription(Diode.DESCRIPTION))) {
|| ve.equalsDescription(Diode.DESCRIPTION)
|| ve.equalsDescription(FGNFET.DESCRIPTION))) {
boolean blown = ve.getElementAttributes().get(Keys.BLOWN);
ve.getElementAttributes().set(Keys.BLOWN, !blown);
hasChanged();

View File

@ -372,6 +372,14 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.</string
<string name="elem_PFET_pin_G">Gate</string>
<string name="elem_PFET_pin_out1">Source</string>
<string name="elem_PFET_pin_out2">Drain</string>
<string name="elem_FGNFET">N-Kanal Floating Gate FET</string>
<string name="elem_FGNFET_tt">N-Kanal Feldeffekttransistor mit Floating Gate. Der Bulk ist mit Masse verbunden jedoch wird der Transistor ohne eine Body-Diode simuliert.
Ist das Floating Gate geladen, ist der Transistor immer sperrend.</string>
<string name="elem_FGNFET_pin_G">Gate</string>
<string name="elem_FGNFET_pin_out2">Source</string>
<string name="elem_FGNFET_pin_out1">Drain</string>
<string name="elem_RotEncoder">Drehencoder</string>
<string name="elem_RotEncoder_tt">Drehknopf mit Drehencoder zur zustandsfreien Erfassung der Drehbewegung.</string>
<string name="elem_RotEncoder_pin_A">Encodersignal A</string>
@ -551,7 +559,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_isProgramMemory">Programmspeicher</string>
<string name="key_isProgramMemory_tt">Zeichnet dieses ROM als Programmspeicher aus. Es kann damit von einer externen IDE beschrieben werden.</string>
<string name="key_Blown">Programmiert</string>
<string name="key_Blown_tt">Wenn gesetzt wird die Diode als "Durchgebrannt" bzw "Programmiert" betrachtet. Diese Einstellung kann direkt über die Taste 'P' verändert werden.</string>
<string name="key_Blown_tt">Wenn gesetzt ist die Diode als "Durchgebrannt" bzw "Programmiert". Bei Floating Gate FETs wird das Gate geladen. Diese Einstellung kann direkt über die Taste 'P' verändert werden.</string>
<string name="key_ExpressionFormat">Format</string>
<string name="key_ExpressionFormat_tt">Anzeigeformat der Ausdrücke.</string>
<string name="key_relayNormallyClosed">Relais ist ein Öffner</string>
@ -702,8 +710,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="menu_runTests_tt">Führt alle Tests in der Schaltung aus!</string>
<string name="menu_actualToDefault">Eingänge übernehmen</string>
<string name="menu_actualToDefault_tt">Aktuelle Eingangswerte als neue Vorgabewerte übernehmen.</string>
<string name="menu_unprogramAllFuses">Alle Dioden zurücksetzen</string>
<string name="menu_unprogramAllFuses_tt">Setzt alle Dioden (Fuses) in den unprogrammierten Zustand zurück. Die Konfiguration geht dabei verloren!</string>
<string name="menu_unprogramAllFuses">Alle Dioden/FGFETS zurücksetzen</string>
<string name="menu_unprogramAllFuses_tt">Setzt alle Dioden (Fuses) bzw. FGFETs in den unprogrammierten Zustand zurück. Die Konfiguration geht dabei verloren!</string>
<string name="menu_programDiode">Diode programmieren</string>
<string name="menu_help_elements">Hilfe</string>
<string name="menu_help_elements_tt">Zeigt eine Dokumentation der vorhandenen Elemente.</string>

View File

@ -354,6 +354,14 @@
<string name="elem_NFET_pin_G">Gate</string>
<string name="elem_NFET_pin_out2">Source</string>
<string name="elem_NFET_pin_out1">Drain</string>
<string name="elem_FGNFET">N-Channel floating gate FET</string>
<string name="elem_FGNFET_tt">N-Channel Floating Gate Field Effect Transitor. The bulk is connected to ground and the transistor is simulated without a body diode.
If there is a charge stored in the floating gate, the fet isn't conducting even if the gate is high.</string>
<string name="elem_FGNFET_pin_G">Gate</string>
<string name="elem_FGNFET_pin_out2">Source</string>
<string name="elem_FGNFET_pin_out1">Drain</string>
<string name="elem_PFET">P-Channel FET</string>
<string name="elem_PFET_tt">P-Channel Field Effect Transitor. The bulk is connected to the pos. voltage rail and the transistor is simulated without a body diode.</string>
<string name="elem_PFET_pin_G">Gate</string>
@ -538,7 +546,7 @@ The names of the variables may not be unique.</string>
<string name="key_isProgramMemory">Program Memory</string>
<string name="key_isProgramMemory_tt">Makes this ROM to program memory. So it can be accessed by an external IDE.</string>
<string name="key_Blown">Programmed</string>
<string name="key_Blown_tt">If set the diode is treated as a "blown" or "programmed" diode or fuse. You can change this setting with the key 'p'.</string>
<string name="key_Blown_tt">If set a diode is "blown" or "programmed". At a floating gate FETS the floating gate is charged. You can change this setting with the key 'p'.</string>
<string name="key_ExpressionFormat">Format</string>
<string name="key_ExpressionFormat_tt">Screen format of expressions.</string>
<string name="key_relayNormallyClosed">Relay is normally closed.</string>
@ -691,8 +699,8 @@ The names of the variables may not be unique.</string>
<string name="menu_runTests_tt">Runs all test cases in the circuit</string>
<string name="menu_actualToDefault">Set Inputs</string>
<string name="menu_actualToDefault_tt">Use actual input values as new default values.</string>
<string name="menu_unprogramAllFuses">Reset all diodes</string>
<string name="menu_unprogramAllFuses_tt">Resets all diodes (fuses) to the unprogramed state. The actual fuse configuration is lost!</string>
<string name="menu_unprogramAllFuses">Reset all diodes and FGFETs</string>
<string name="menu_unprogramAllFuses_tt">Resets all diodes (fuses) and FGFETs to the unprogramed state. The actual fuse configuration is lost!</string>
<string name="menu_programDiode">Program diode</string>
<string name="menu_help_elements">Components</string>
<string name="menu_help_elements_tt">Shows a list of all available components.</string>

View File

@ -39,8 +39,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(53, new FileScanner(this::check).scan(examples));
assertEquals(47, testCasesInFiles);
assertEquals(54, new FileScanner(this::check).scan(examples));
assertEquals(48, testCasesInFiles);
}

File diff suppressed because it is too large Load Diff