mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-27 06:51:37 -04:00
Added an EEPROM
This commit is contained in:
parent
6a8cf51379
commit
2419580875
104
src/main/java/de/neemann/digital/core/memory/EEPROM.java
Normal file
104
src/main/java/de/neemann/digital/core/memory/EEPROM.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -135,6 +135,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
.add(RAMDualPort.DESCRIPTION)
|
.add(RAMDualPort.DESCRIPTION)
|
||||||
.add(RAMSinglePort.DESCRIPTION)
|
.add(RAMSinglePort.DESCRIPTION)
|
||||||
.add(RAMSinglePortSel.DESCRIPTION)
|
.add(RAMSinglePortSel.DESCRIPTION)
|
||||||
|
.add(EEPROM.DESCRIPTION)
|
||||||
.add(GraphicCard.DESCRIPTION)
|
.add(GraphicCard.DESCRIPTION)
|
||||||
.add(Counter.DESCRIPTION))
|
.add(Counter.DESCRIPTION))
|
||||||
.add(new LibraryNode(Lang.get("lib_arithmetic"))
|
.add(new LibraryNode(Lang.get("lib_arithmetic"))
|
||||||
|
@ -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.
|
<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>
|
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">Grafik-RAM</string>
|
||||||
<string name="elem_GraphicCard_tt">Wird verwendet um Bitmap Grafiken anzuzeigen. Der Baustein verhält sich wie ein
|
<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
|
RAM-Baustein mit dem Unterschied, dass der RAM-Inhalt als Grafik angezeigt wird. Jede Speicherstelle definiert die Farbe
|
||||||
|
@ -268,6 +268,15 @@
|
|||||||
<string name="elem_RAMSinglePortSel_tt">A RAM module with a bidirectional connection for reading and writing the data.
|
<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>
|
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">Graphic RAM</string>
|
||||||
<string name="elem_GraphicCard_tt">Used to show a bitmap graphic. This element works similar to a RAM. In addition it
|
<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
|
shows its content on a graphic screen. Every pixel is represented by a memory address. There are to screens supported
|
||||||
|
@ -40,8 +40,8 @@ public class TestExamples extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testTestExamples() throws Exception {
|
public void testTestExamples() throws Exception {
|
||||||
File examples = new File(Resources.getRoot(), "/dig/test");
|
File examples = new File(Resources.getRoot(), "/dig/test");
|
||||||
assertEquals(100, new FileScanner(this::check).scan(examples));
|
assertEquals(101, new FileScanner(this::check).scan(examples));
|
||||||
assertEquals(91, testCasesInFiles);
|
assertEquals(93, testCasesInFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
194
src/test/resources/dig/test/eeprom.dig
Normal file
194
src/test/resources/dig/test/eeprom.dig
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user