Added an EEPROM

This commit is contained in:
hneemann 2017-09-06 15:56:33 +02:00
parent 6a8cf51379
commit 2419580875
6 changed files with 319 additions and 2 deletions

View File

@ -0,0 +1,104 @@
package de.neemann.digital.core.memory;
import de.neemann.digital.core.Node;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
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 static de.neemann.digital.core.element.PinInfo.input;
/**
* A EEPROM module.
*
* @author hneemann
*/
public class EEPROM extends Node implements Element {
/**
* The EEPROMs {@link ElementTypeDescription}
*/
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(EEPROM.class,
input("A"),
input("CS"),
input("WE"),
input("OE"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.ADDR_BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.DATA);
private final int bits;
private final int addrBits;
private final DataField memory;
private final ObservableValue dataOut;
private ObservableValue addrIn;
private ObservableValue csIn;
private ObservableValue weIn;
private ObservableValue oeIn;
private ObservableValue dataIn;
private int addr;
private boolean cs;
private boolean oe;
/**
* Creates a new instance
*
* @param attr the elements attributes
*/
public EEPROM(ElementAttributes attr) {
super(true);
bits = attr.get(Keys.BITS);
addrBits = attr.get(Keys.ADDR_BITS);
int size = 1 << addrBits;
DataField memory = attr.get(Keys.DATA);
if (memory.size() < size) {
memory = new DataField(memory, size);
attr.set(Keys.DATA, memory);
}
this.memory = memory;
dataOut = new ObservableValue("D", bits, true).setPinDescription(DESCRIPTION).setBidirectional();
}
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this);
csIn = inputs.get(1).checkBits(1, this).addObserverToValue(this);
weIn = inputs.get(2).checkBits(1, this).addObserverToValue(this);
oeIn = inputs.get(3).checkBits(1, this).addObserverToValue(this);
dataIn = inputs.get(4).checkBits(bits, this).addObserverToValue(this);
}
@Override
public void readInputs() throws NodeException {
cs = csIn.getBool();
if (cs) {
addr = (int) addrIn.getValue();
oe = oeIn.getBool();
if (weIn.getBool()) {
long data = dataIn.getValue();
memory.setData(addr, data);
}
}
}
@Override
public void writeOutputs() throws NodeException {
if (cs && oe) {
dataOut.set(memory.getDataWord(addr), false);
} else {
dataOut.set(0, true);
}
}
@Override
public ObservableValues getOutputs() {
return dataOut.asList();
}
}

View File

@ -135,6 +135,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
.add(RAMDualPort.DESCRIPTION)
.add(RAMSinglePort.DESCRIPTION)
.add(RAMSinglePortSel.DESCRIPTION)
.add(EEPROM.DESCRIPTION)
.add(GraphicCard.DESCRIPTION)
.add(Counter.DESCRIPTION))
.add(new LibraryNode(Lang.get("lib_arithmetic"))

View File

@ -272,6 +272,15 @@ Es können sowohl komplette Takte als auch einzelne Gatter-Veränderungen angeze
<string name="elem_RAMSinglePortSel_tt">Ein RAM-Baustein mit einem bidirektionellem Anschluss für das Lesen und Schreiben von Daten.
Es gibt einen CS-Eingang. Mit diesem können mehrere solcher Bausteine mit einem Adressdekoder zu einem größeren RAM zusammengeschaltet werden.</string>
<string name="elem_EEPROM">EEPROM</string>
<string name="elem_EEPROM_pin_A">Die Adresse, an der gelesen und geschrieben wird.</string>
<string name="elem_EEPROM_pin_WE">Bei einer 1 werden die Daten in das EEPROM geschrieben.</string>
<string name="elem_EEPROM_pin_D">Der bidirektionale Datenanschluß.</string>
<string name="elem_EEPROM_pin_CS">Ist dieser Eingang 1 ist der Baustein aktiv.</string>
<string name="elem_EEPROM_pin_OE">Ist dieser Eingang 1 wird das Datenwort ausgegeben.</string>
<string name="elem_EEPROM_tt">Ein EEPROM-Baustein mit einem bidirektionellem Anschluss für das Lesen und Schreiben von Daten.
Es gibt einen CS-Eingang. Mit diesem können mehrere solcher Bausteine mit einem Adressdekoder zu einem größeren EEPROM zusammengeschaltet werden.</string>
<string name="elem_GraphicCard">Grafik-RAM</string>
<string name="elem_GraphicCard_tt">Wird verwendet um Bitmap Grafiken anzuzeigen. Der Baustein verhält sich wie ein
RAM-Baustein mit dem Unterschied, dass der RAM-Inhalt als Grafik angezeigt wird. Jede Speicherstelle definiert die Farbe

View File

@ -268,6 +268,15 @@
<string name="elem_RAMSinglePortSel_tt">A RAM module with a bidirectional connection for reading and writing the data.
The CS input allows to build a larger RAM from some smaller RAMs and a address decoder.</string>
<string name="elem_EEPROM">EEPROM</string>
<string name="elem_EEPROM_pin_A">The address to read and write.</string>
<string name="elem_EEPROM_pin_WE">If set to high the data is written to the EEPROM.</string>
<string name="elem_EEPROM_pin_D">The bidirectional data connection.</string>
<string name="elem_EEPROM_pin_CS">If this input is high, this EEPROM is enabled. Otherwise the output is always in high Z state.</string>
<string name="elem_EEPROM_pin_OE">If this input is high, the stored value is output.</string>
<string name="elem_EEPROM_tt">A EEPROM module with a bidirectional connection for reading and writing the data.
The CS input allows to build a larger EEPROM from some smaller EEPROMs and a address decoder.</string>
<string name="elem_GraphicCard">Graphic RAM</string>
<string name="elem_GraphicCard_tt">Used to show a bitmap graphic. This element works similar to a RAM. In addition it
shows its content on a graphic screen. Every pixel is represented by a memory address. There are to screens supported

View File

@ -40,8 +40,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(100, new FileScanner(this::check).scan(examples));
assertEquals(91, testCasesInFiles);
assertEquals(101, new FileScanner(this::check).scan(examples));
assertEquals(93, testCasesInFiles);
}

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>EEPROM</elementName>
<elementAttributes>
<entry>
<string>AddrBits</string>
<int>8</int>
</entry>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
<entry>
<string>Data</string>
<data size="256"></data>
</entry>
<entry>
<string>lastDataFile</string>
<string>/home/hneemann/temp/z/z.hex</string>
</entry>
</elementAttributes>
<pos x="520" y="220"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="400" y="220"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>CS</string>
</entry>
</elementAttributes>
<pos x="500" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>OE</string>
</entry>
</elementAttributes>
<pos x="500" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>WE</string>
</entry>
</elementAttributes>
<pos x="400" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D_out</string>
</entry>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="620" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>D_in</string>
</entry>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
<entry>
<string>isHighZ</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="400" y="180"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>first</string>
</entry>
<entry>
<string>Testdata</string>
<testData>
<dataString>A CS OE WE D_in D_out
0 0 0 0 Z Z
# write to EEPROM
loop(n,30)
(n) 1 0 0 (n) (n)
(n) 1 0 1 (n) (n)
end loop
# read from EEPROM
loop(n,30)
(n) 1 1 0 Z (n)
end loop
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="640" y="260"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>second</string>
</entry>
<entry>
<string>Testdata</string>
<testData>
<dataString>A CS OE WE D_in D_out
0 0 0 0 Z Z
# Data written by the first test case
# is still present in the EEPROM.
# read from EEPROM
loop(n,30)
(n) 1 1 0 Z (n)
end loop
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="640" y="340"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="500" y="240"/>
<p2 x="520" y="240"/>
</wire>
<wire>
<p1 x="580" y="260"/>
<p2 x="600" y="260"/>
</wire>
<wire>
<p1 x="400" y="180"/>
<p2 x="600" y="180"/>
</wire>
<wire>
<p1 x="600" y="180"/>
<p2 x="620" y="180"/>
</wire>
<wire>
<p1 x="400" y="280"/>
<p2 x="520" y="280"/>
</wire>
<wire>
<p1 x="400" y="220"/>
<p2 x="520" y="220"/>
</wire>
<wire>
<p1 x="500" y="300"/>
<p2 x="520" y="300"/>
</wire>
<wire>
<p1 x="600" y="180"/>
<p2 x="600" y="260"/>
</wire>
</wires>
</circuit>