Added a floating gate P channel fet

This commit is contained in:
hneemann 2017-04-15 18:50:04 +02:00
parent 1580e4dbd0
commit 473cf93297
18 changed files with 509 additions and 33 deletions

View File

@ -195,4 +195,13 @@ public class ElementTypeDescription {
return elementFactory.create(elementAttributes);
}
/**
* Returns true if this description contains the given key
*
* @param key the key
* @return true if this description contains the given key
*/
public boolean hasAttribute(Key key) {
return attributeList.contains(key);
}
}

View File

@ -8,7 +8,7 @@ import de.neemann.digital.core.element.Keys;
import static de.neemann.digital.core.element.PinInfo.input;
/**
* P-Channel MOS FET
* N-Channel floating gate MOS FET
* Created by hneemann on 22.02.17.
*/
public class FGNFET extends NFET {

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 floating gate MOS FET
* Created by hneemann on 22.02.17.
*/
public class FGPFET extends NFET {
/**
* The switch description
*/
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(FGPFET.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 FGPFET(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

@ -12,15 +12,12 @@ import de.neemann.digital.core.io.IntFormat;
import de.neemann.digital.core.io.Out;
import de.neemann.digital.core.memory.DataField;
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;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.shapes.Drawable;
import de.neemann.digital.draw.shapes.InputShape;
import de.neemann.digital.draw.shapes.ShapeFactory;
@ -610,13 +607,12 @@ public class Circuit {
/**
* All fuses (diodes) are set to unprogramed so that they are working again.
*
* @param library library to determine which elements are programmable
*/
public void unprogramAllFuses() {
public void unprogramAllFuses(ElementLibrary library) {
for (VisualElement ve : visualElements)
if (ve.equalsDescription(DiodeForeward.DESCRIPTION)
|| ve.equalsDescription(DiodeBackward.DESCRIPTION)
|| ve.equalsDescription(Diode.DESCRIPTION)
|| ve.equalsDescription(FGNFET.DESCRIPTION)) {
if (library.isProgrammable(ve.getElementName())) {
ve.getElementAttributes().set(Keys.BLOWN, false);
modified = true;
}

View File

@ -12,10 +12,13 @@ public class Style {
* maximal line thickness
*/
public static final int MAXLINETHICK = 4;
/**
* thickness of thin lines
*/
public static final int LINETHIN = MAXLINETHICK / 2;
private static final int WIRETHICK = MAXLINETHICK;
private static final int LINETHICK = MAXLINETHICK;
private static final int LINETHIN = MAXLINETHICK / 2;
private static final int LINEDASH = 1;
/**

View File

@ -1,6 +1,7 @@
package de.neemann.digital.draw.library;
import de.neemann.digital.core.arithmetic.*;
import de.neemann.digital.core.arithmetic.Comparator;
import de.neemann.digital.core.basic.*;
import de.neemann.digital.core.element.*;
import de.neemann.digital.core.flipflops.FlipflopD;
@ -30,10 +31,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.*;
/**
* The ElementLibrary is responsible for storing all the components which can be used in a circuit.
@ -50,6 +48,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
private static final Logger LOGGER = LoggerFactory.getLogger(ElementLibrary.class);
private final HashMap<String, LibraryNode> map = new HashMap<>();
private final HashSet<String> isProgrammable = new HashSet<>();
private final ArrayList<LibraryListener> listeners = new ArrayList<>();
private final LibraryNode root;
private ShapeFactory shapeFactory;
@ -128,8 +127,9 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
.add(DiodeBackward.DESCRIPTION)
.add(Switch.DESCRIPTION)
.add(Relay.DESCRIPTION)
.add(NFET.DESCRIPTION)
.add(PFET.DESCRIPTION)
.add(NFET.DESCRIPTION)
.add(FGPFET.DESCRIPTION)
.add(FGNFET.DESCRIPTION)
.add(Reset.DESCRIPTION)
.add(Break.DESCRIPTION))
@ -137,6 +137,23 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
.add(TestCaseElement.TESTCASEDESCRIPTION));
populateNodeMap();
isProgrammable.clear();
root.traverse(libraryNode -> {
ElementTypeDescription d = libraryNode.getDescriptionOrNull();
if (d != null && d.hasAttribute(Keys.BLOWN))
isProgrammable.add(d.getName());
});
}
/**
* Returns true if element is programmable
*
* @param name the name
* @return true if it is programmable
*/
public boolean isProgrammable(String name) {
return isProgrammable.contains(name);
}
/**

View File

@ -120,6 +120,16 @@ public class LibraryNode implements Iterable<LibraryNode> {
return description != null;
}
/**
* Returns the description of the element
*
* @return the description, null if not available
**/
public ElementTypeDescription getDescriptionOrNull() {
return description;
}
/**
* Returns the description of the element
*

View File

@ -10,6 +10,8 @@ import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import java.awt.*;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
@ -17,6 +19,7 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
* The n-chan FET shape
*/
public class FGFETShapeN extends FETShape {
static final Style CHARGED_GATE = new Style(Style.MAXLINETHICK, false, Color.RED);
private final boolean programmed;
@ -46,7 +49,7 @@ public class FGFETShapeN extends FETShape {
super.drawTo(graphic, highLight);
if (programmed)
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), Style.HIGHLIGHT);
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), CHARGED_GATE);
else
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), Style.THIN);

View File

@ -0,0 +1,64 @@
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.FGFETShapeN.CHARGED_GATE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
/**
* The p-chan FET shape
*/
public class FGFETShapeP extends FETShape {
private final boolean programmed;
/**
* Creates a new instance
*
* @param attributes the attributes
* @param inputs the inputs
* @param outputs the outputs
*/
public FGFETShapeP(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, 0), 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), CHARGED_GATE);
else
graphic.drawLine(new Vector(6, 2 * SIZE - 4), new Vector(6, 4), Style.THIN);
// the arrow
graphic.drawLine(new Vector(SIZE2 +1, SIZE), new Vector(SIZE2 + 6, SIZE), Style.THIN);
graphic.drawPolygon(new Polygon(true)
.add(SIZE - SIZE2 / 3 + 4, SIZE)
.add(SIZE2 + 6, SIZE - SIZE2 / 4)
.add(SIZE2 + 6, SIZE + SIZE2 / 4), Style.THIN_FILLED);
}
}

View File

@ -86,6 +86,7 @@ public final class ShapeFactory {
map.put(Relay.DESCRIPTION.getName(), RelayShape::new);
map.put(NFET.DESCRIPTION.getName(), FETShapeN::new);
map.put(FGNFET.DESCRIPTION.getName(), FGFETShapeN::new);
map.put(FGPFET.DESCRIPTION.getName(), FGFETShapeP::new);
map.put(PFET.DESCRIPTION.getName(), FETShapeP::new);
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);

View File

@ -540,7 +540,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
ToolTipAction unprogramAllFuses = new ToolTipAction(Lang.get("menu_unprogramAllFuses")) {
@Override
public void actionPerformed(ActionEvent e) {
circuitComponent.getCircuit().unprogramAllFuses();
circuitComponent.getCircuit().unprogramAllFuses(library);
stoppedState.enter();
}
}.setToolTip(Lang.get("menu_unprogramAllFuses_tt"));

View File

@ -7,10 +7,6 @@ import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.ImmutableList;
import de.neemann.digital.core.element.Key;
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;
@ -167,7 +163,7 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
@Override
public void actionPerformed(ActionEvent e) {
if (activeMouseController instanceof MouseControllerNormal) {
programDiodeAt(getPosVector(lastMousePos.x, lastMousePos.y));
programElementAt(getPosVector(lastMousePos.x, lastMousePos.y));
}
}
};
@ -233,14 +229,12 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
setToolTipText("");
}
private void programDiodeAt(Vector pos) {
private void programElementAt(Vector pos) {
VisualElement ve = circuit.getElementAt(pos);
if (ve != null && (ve.equalsDescription(DiodeBackward.DESCRIPTION)
|| ve.equalsDescription(DiodeForeward.DESCRIPTION)
|| ve.equalsDescription(Diode.DESCRIPTION)
|| ve.equalsDescription(FGNFET.DESCRIPTION))) {
if (ve != null && library.isProgrammable(ve.getElementName())) {
boolean blown = ve.getElementAttributes().get(Keys.BLOWN);
ve.getElementAttributes().set(Keys.BLOWN, !blown);
circuit.modified();
hasChanged();
}
}

View File

@ -380,6 +380,13 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.</string
<string name="elem_FGNFET_pin_out2">Source</string>
<string name="elem_FGNFET_pin_out1">Drain</string>
<string name="elem_FGPFET">P-Kanal Floating Gate FET</string>
<string name="elem_FGPFET_tt">P-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_FGPFET_pin_G">Gate</string>
<string name="elem_FGPFET_pin_out1">Source</string>
<string name="elem_FGPFET_pin_out2">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>

View File

@ -350,20 +350,27 @@
<string name="elem_PullDown_pin_out">A "weak low".</string>
<string name="elem_NFET">N-Channel FET</string>
<string name="elem_NFET_tt">N-Channel Field Effect Transitor. The bulk is connected to ground and the transistor is simulated without a body diode.</string>
<string name="elem_NFET_tt">N-Channel Field Effect Transistor. The bulk is connected to ground and the transistor is simulated without a body diode.</string>
<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.
<string name="elem_FGNFET_tt">N-Channel Floating Gate Field Effect Transistor. 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_FGPFET">P-Channel floating gate FET</string>
<string name="elem_FGPFET_tt">P-Channel Floating Gate Field Effect Transistor. 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 low.</string>
<string name="elem_FGPFET_pin_G">Gate</string>
<string name="elem_FGPFET_pin_out1">Source</string>
<string name="elem_FGPFET_pin_out2">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_tt">P-Channel Field Effect Transistor. 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>
<string name="elem_PFET_pin_out1">Source</string>
<string name="elem_PFET_pin_out2">Drain</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(54, new FileScanner(this::check).scan(examples));
assertEquals(48, testCasesInFiles);
assertEquals(56, new FileScanner(this::check).scan(examples));
assertEquals(52, testCasesInFiles);
}

View File

@ -412,6 +412,16 @@
<elementAttributes/>
<pos x="680" y="540"/>
</visualElement>
<visualElement>
<elementName>FGPFET</elementName>
<elementAttributes/>
<pos x="880" y="640"/>
</visualElement>
<visualElement>
<elementName>FGNFET</elementName>
<elementAttributes/>
<pos x="840" y="640"/>
</visualElement>
</visualElements>
<wires/>
</circuit>

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<visualElements>
<visualElement>
<elementName>FGNFET</elementName>
<elementAttributes/>
<pos x="380" y="200"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="400" y="160"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="400" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A_1</string>
</entry>
</elementAttributes>
<pos x="360" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y_1</string>
</entry>
</elementAttributes>
<pos x="420" y="180"/>
</visualElement>
<visualElement>
<elementName>FGNFET</elementName>
<elementAttributes>
<entry>
<string>Blown</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="640" y="200"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="660" y="160"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="660" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A_2</string>
</entry>
</elementAttributes>
<pos x="620" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y_2</string>
</entry>
</elementAttributes>
<pos x="680" y="180"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A_1 Y_1
0 1
1 0
z 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="340" y="320"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A_2 Y_2
0 1
1 1
z 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="600" y="320"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="360" y="240"/>
<p2 x="380" y="240"/>
</wire>
<wire>
<p1 x="620" y="240"/>
<p2 x="640" y="240"/>
</wire>
<wire>
<p1 x="400" y="180"/>
<p2 x="420" y="180"/>
</wire>
<wire>
<p1 x="660" y="180"/>
<p2 x="680" y="180"/>
</wire>
<wire>
<p1 x="400" y="160"/>
<p2 x="400" y="180"/>
</wire>
<wire>
<p1 x="400" y="240"/>
<p2 x="400" y="260"/>
</wire>
<wire>
<p1 x="400" y="180"/>
<p2 x="400" y="200"/>
</wire>
<wire>
<p1 x="660" y="160"/>
<p2 x="660" y="180"/>
</wire>
<wire>
<p1 x="660" y="240"/>
<p2 x="660" y="260"/>
</wire>
<wire>
<p1 x="660" y="180"/>
<p2 x="660" y="200"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A_1</string>
</entry>
</elementAttributes>
<pos x="360" y="120"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y_1</string>
</entry>
</elementAttributes>
<pos x="420" y="180"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A_1 Y_1
0 1
1 0
Z 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="340" y="300"/>
</visualElement>
<visualElement>
<elementName>FGPFET</elementName>
<elementAttributes/>
<pos x="380" y="120"/>
</visualElement>
<visualElement>
<elementName>PullDown</elementName>
<elementAttributes/>
<pos x="400" y="200"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="400" y="100"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A_2</string>
</entry>
</elementAttributes>
<pos x="620" y="120"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y_2</string>
</entry>
</elementAttributes>
<pos x="680" y="180"/>
</visualElement>
<visualElement>
<elementName>FGPFET</elementName>
<elementAttributes>
<entry>
<string>Blown</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="640" y="120"/>
</visualElement>
<visualElement>
<elementName>PullDown</elementName>
<elementAttributes/>
<pos x="660" y="200"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="660" y="100"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A_2 Y_2
0 0
1 0
Z 0
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="600" y="300"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="400" y="180"/>
<p2 x="420" y="180"/>
</wire>
<wire>
<p1 x="660" y="180"/>
<p2 x="680" y="180"/>
</wire>
<wire>
<p1 x="360" y="120"/>
<p2 x="380" y="120"/>
</wire>
<wire>
<p1 x="620" y="120"/>
<p2 x="640" y="120"/>
</wire>
<wire>
<p1 x="400" y="160"/>
<p2 x="400" y="180"/>
</wire>
<wire>
<p1 x="400" y="100"/>
<p2 x="400" y="120"/>
</wire>
<wire>
<p1 x="400" y="180"/>
<p2 x="400" y="200"/>
</wire>
<wire>
<p1 x="660" y="160"/>
<p2 x="660" y="180"/>
</wire>
<wire>
<p1 x="660" y="100"/>
<p2 x="660" y="120"/>
</wire>
<wire>
<p1 x="660" y="180"/>
<p2 x="660" y="200"/>
</wire>
</wires>
</circuit>