mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 07:17:13 -04:00
fixed a bug in one of the RAMs
This commit is contained in:
parent
46f964c2b8
commit
5ac29aa857
@ -5,6 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.core.memory;
|
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.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
@ -15,7 +20,7 @@ import static de.neemann.digital.core.element.PinInfo.input;
|
|||||||
/**
|
/**
|
||||||
* A EEPROM module.
|
* A EEPROM module.
|
||||||
*/
|
*/
|
||||||
public class EEPROM extends RAMSinglePortSel implements ROMInterface {
|
public class EEPROM extends Node implements Element, RAMInterface, ROMInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The EEPROMs {@link ElementTypeDescription}
|
* The EEPROMs {@link ElementTypeDescription}
|
||||||
@ -33,17 +38,129 @@ public class EEPROM extends RAMSinglePortSel implements ROMInterface {
|
|||||||
.addAttribute(Keys.INVERTER_CONFIG)
|
.addAttribute(Keys.INVERTER_CONFIG)
|
||||||
.addAttribute(Keys.DATA);
|
.addAttribute(Keys.DATA);
|
||||||
|
|
||||||
|
private final int bits;
|
||||||
|
private final int addrBits;
|
||||||
|
private final int size;
|
||||||
|
private final String label;
|
||||||
|
private final ObservableValue dataOut;
|
||||||
|
private final boolean isProgramMemory;
|
||||||
|
private DataField memory;
|
||||||
|
private ObservableValue addrIn;
|
||||||
|
private ObservableValue csIn;
|
||||||
|
private ObservableValue weIn;
|
||||||
|
private ObservableValue oeIn;
|
||||||
|
private ObservableValue dataIn;
|
||||||
|
|
||||||
|
private int readAddr;
|
||||||
|
private int writeAddr;
|
||||||
|
private boolean cs;
|
||||||
|
private boolean oe;
|
||||||
|
private boolean we;
|
||||||
|
private boolean lastWrite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
*
|
*
|
||||||
* @param attr the elements attributes
|
* @param attr the elements attributes
|
||||||
*/
|
*/
|
||||||
public EEPROM(ElementAttributes attr) {
|
public EEPROM(ElementAttributes attr) {
|
||||||
super(attr);
|
super(true);
|
||||||
|
bits = attr.get(Keys.BITS);
|
||||||
|
addrBits = attr.get(Keys.ADDR_BITS);
|
||||||
|
size = 1 << addrBits;
|
||||||
|
memory = attr.get(Keys.DATA);
|
||||||
|
label = attr.getLabel();
|
||||||
|
dataOut = new ObservableValue("D", bits)
|
||||||
|
.setToHighZ()
|
||||||
|
.setPinDescription(DESCRIPTION)
|
||||||
|
.setBidirectional();
|
||||||
|
isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DataField createDataField(ElementAttributes attr, int size) {
|
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||||
return attr.get(Keys.DATA);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
cs = csIn.getBool();
|
||||||
|
if (cs) {
|
||||||
|
readAddr = (int) addrIn.getValue();
|
||||||
|
oe = oeIn.getBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
we = weIn.getBool();
|
||||||
|
boolean write = cs && we;
|
||||||
|
if (write && !lastWrite)
|
||||||
|
writeAddr = (int) addrIn.getValue();
|
||||||
|
|
||||||
|
if (!write && lastWrite) {
|
||||||
|
long data = dataIn.getValue();
|
||||||
|
memory.setData(writeAddr, data);
|
||||||
|
}
|
||||||
|
lastWrite = write;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
if (cs && oe && !we) {
|
||||||
|
dataOut.setValue(memory.getDataWord(readAddr));
|
||||||
|
} else {
|
||||||
|
dataOut.setToHighZ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableValues getOutputs() {
|
||||||
|
return dataOut.asList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataField getMemory() {
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDataBits() {
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAddrBits() {
|
||||||
|
return addrBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the rams data
|
||||||
|
*
|
||||||
|
* @param data the data to set
|
||||||
|
*/
|
||||||
|
public void setData(DataField data) {
|
||||||
|
this.memory = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isProgramMemory() {
|
||||||
|
return isProgramMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProgramMemory(DataField dataField) {
|
||||||
|
memory.setDataFrom(dataField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.core.memory;
|
package de.neemann.digital.core.memory;
|
||||||
|
|
||||||
import de.neemann.digital.core.*;
|
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.Element;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.draw.elements.PinException;
|
|
||||||
|
|
||||||
import static de.neemann.digital.core.element.PinInfo.input;
|
import static de.neemann.digital.core.element.PinInfo.input;
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMSinglePortSel.class,
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMSinglePortSel.class,
|
||||||
input("A"),
|
input("A"),
|
||||||
input("CS"),
|
input("CS"),
|
||||||
input("WE").setClock(),
|
input("WE"),
|
||||||
input("OE"))
|
input("OE"))
|
||||||
.addAttribute(Keys.ROTATE)
|
.addAttribute(Keys.ROTATE)
|
||||||
.addAttribute(Keys.BITS)
|
.addAttribute(Keys.BITS)
|
||||||
@ -48,12 +50,10 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
private ObservableValue oeIn;
|
private ObservableValue oeIn;
|
||||||
private ObservableValue dataIn;
|
private ObservableValue dataIn;
|
||||||
|
|
||||||
private int readAddr;
|
private int addr;
|
||||||
private int writeAddr;
|
|
||||||
private boolean cs;
|
private boolean cs;
|
||||||
private boolean oe;
|
private boolean oe;
|
||||||
private boolean we;
|
private boolean we;
|
||||||
private boolean lastWrite;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -65,7 +65,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
bits = attr.get(Keys.BITS);
|
bits = attr.get(Keys.BITS);
|
||||||
addrBits = attr.get(Keys.ADDR_BITS);
|
addrBits = attr.get(Keys.ADDR_BITS);
|
||||||
size = 1 << addrBits;
|
size = 1 << addrBits;
|
||||||
memory = createDataField(attr, size);
|
memory = new DataField(size);
|
||||||
label = attr.getLabel();
|
label = attr.getLabel();
|
||||||
dataOut = new ObservableValue("D", bits)
|
dataOut = new ObservableValue("D", bits)
|
||||||
.setToHighZ()
|
.setToHighZ()
|
||||||
@ -74,57 +74,40 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
|
|||||||
isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY);
|
isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* creates the data field to use
|
|
||||||
*
|
|
||||||
* @param attr the elements attributes
|
|
||||||
* @param size the size of the memory
|
|
||||||
* @return the memory to use
|
|
||||||
*/
|
|
||||||
protected DataField createDataField(ElementAttributes attr, int size) {
|
|
||||||
return new DataField(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInputs(ObservableValues inputs) throws NodeException {
|
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||||
addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this);
|
addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this);
|
||||||
csIn = inputs.get(1).checkBits(1, this).addObserverToValue(this);
|
csIn = inputs.get(1).checkBits(1, this).addObserverToValue(this);
|
||||||
weIn = inputs.get(2).checkBits(1, this).addObserverToValue(this);
|
weIn = inputs.get(2).checkBits(1, this).addObserverToValue(this);
|
||||||
oeIn = inputs.get(3).checkBits(1, this).addObserverToValue(this);
|
oeIn = inputs.get(3).checkBits(1, this).addObserverToValue(this);
|
||||||
dataIn = inputs.get(4).checkBits(bits, this);
|
dataIn = inputs.get(4).checkBits(bits, this).addObserverToValue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readInputs() throws NodeException {
|
public void readInputs() throws NodeException {
|
||||||
cs = csIn.getBool();
|
cs = csIn.getBool();
|
||||||
if (cs) {
|
if (cs) {
|
||||||
readAddr = (int) addrIn.getValue();
|
addr = (int) addrIn.getValue();
|
||||||
oe = oeIn.getBool();
|
oe = oeIn.getBool();
|
||||||
}
|
|
||||||
|
|
||||||
we = weIn.getBool();
|
we = weIn.getBool();
|
||||||
boolean write = cs && we;
|
if (we) {
|
||||||
if (write && !lastWrite)
|
|
||||||
writeAddr = (int) addrIn.getValue();
|
|
||||||
|
|
||||||
if (!write && lastWrite) {
|
|
||||||
long data = dataIn.getValue();
|
long data = dataIn.getValue();
|
||||||
memory.setData(writeAddr, data);
|
memory.setData(addr, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastWrite = write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeOutputs() throws NodeException {
|
public void writeOutputs() throws NodeException {
|
||||||
if (cs && oe && !we) {
|
if (cs && oe && !we) {
|
||||||
dataOut.setValue(memory.getDataWord(readAddr));
|
dataOut.setValue(memory.getDataWord(addr));
|
||||||
} else {
|
} else {
|
||||||
dataOut.setToHighZ();
|
dataOut.setToHighZ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValues getOutputs() throws PinException {
|
public ObservableValues getOutputs() {
|
||||||
return dataOut.asList();
|
return dataOut.asList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,11 +16,14 @@ import de.neemann.digital.core.element.Keys;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
import static de.neemann.digital.core.element.PinInfo.input;
|
import static de.neemann.digital.core.element.PinInfo.input;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class Terminal extends Node implements Element {
|
public class Terminal extends Node implements Element {
|
||||||
|
private static final boolean HEADLESS = GraphicsEnvironment.isHeadless();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The terminal description
|
* The terminal description
|
||||||
@ -70,7 +73,7 @@ public class Terminal extends Node implements Element {
|
|||||||
boolean clockVal = clock.getBool();
|
boolean clockVal = clock.getBool();
|
||||||
if (!lastClock && clockVal && en.getBool()) {
|
if (!lastClock && clockVal && en.getBool()) {
|
||||||
long value = data.getValue();
|
long value = data.getValue();
|
||||||
if (value != 0)
|
if (value != 0 && !HEADLESS)
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
if (terminalDialog == null || !terminalDialog.isVisible()) {
|
if (terminalDialog == null || !terminalDialog.isVisible()) {
|
||||||
terminalDialog = new TerminalDialog(getModel().getWindowPosManager().getMainFrame(), attr);
|
terminalDialog = new TerminalDialog(getModel().getWindowPosManager().getMainFrame(), attr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user