fixed a bug in one of the RAMs

This commit is contained in:
hneemann 2019-06-10 21:22:10 +02:00
parent 46f964c2b8
commit 5ac29aa857
3 changed files with 141 additions and 38 deletions

View File

@ -5,6 +5,11 @@
*/
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;
@ -15,7 +20,7 @@ import static de.neemann.digital.core.element.PinInfo.input;
/**
* A EEPROM module.
*/
public class EEPROM extends RAMSinglePortSel implements ROMInterface {
public class EEPROM extends Node implements Element, RAMInterface, ROMInterface {
/**
* The EEPROMs {@link ElementTypeDescription}
@ -33,17 +38,129 @@ public class EEPROM extends RAMSinglePortSel implements ROMInterface {
.addAttribute(Keys.INVERTER_CONFIG)
.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
*
* @param attr the elements attributes
*/
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
protected DataField createDataField(ElementAttributes attr, int size) {
return attr.get(Keys.DATA);
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);
}
@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);
}
}

View File

@ -5,12 +5,14 @@
*/
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.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.PinException;
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,
input("A"),
input("CS"),
input("WE").setClock(),
input("WE"),
input("OE"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
@ -48,12 +50,10 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
private ObservableValue oeIn;
private ObservableValue dataIn;
private int readAddr;
private int writeAddr;
private int addr;
private boolean cs;
private boolean oe;
private boolean we;
private boolean lastWrite;
/**
* Creates a new instance
@ -65,7 +65,7 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
bits = attr.get(Keys.BITS);
addrBits = attr.get(Keys.ADDR_BITS);
size = 1 << addrBits;
memory = createDataField(attr, size);
memory = new DataField(size);
label = attr.getLabel();
dataOut = new ObservableValue("D", bits)
.setToHighZ()
@ -74,57 +74,40 @@ public class RAMSinglePortSel extends Node implements Element, RAMInterface {
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
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);
dataIn = inputs.get(4).checkBits(bits, this).addObserverToValue(this);
}
@Override
public void readInputs() throws NodeException {
cs = csIn.getBool();
if (cs) {
readAddr = (int) addrIn.getValue();
addr = (int) addrIn.getValue();
oe = oeIn.getBool();
we = weIn.getBool();
if (we) {
long data = dataIn.getValue();
memory.setData(addr, data);
}
}
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));
dataOut.setValue(memory.getDataWord(addr));
} else {
dataOut.setToHighZ();
}
}
@Override
public ObservableValues getOutputs() throws PinException {
public ObservableValues getOutputs() {
return dataOut.asList();
}

View File

@ -16,11 +16,14 @@ import de.neemann.digital.core.element.Keys;
import javax.swing.*;
import java.awt.*;
import static de.neemann.digital.core.element.PinInfo.input;
/**
*/
public class Terminal extends Node implements Element {
private static final boolean HEADLESS = GraphicsEnvironment.isHeadless();
/**
* The terminal description
@ -70,7 +73,7 @@ public class Terminal extends Node implements Element {
boolean clockVal = clock.getBool();
if (!lastClock && clockVal && en.getBool()) {
long value = data.getValue();
if (value != 0)
if (value != 0 && !HEADLESS)
SwingUtilities.invokeLater(() -> {
if (terminalDialog == null || !terminalDialog.isVisible()) {
terminalDialog = new TerminalDialog(getModel().getWindowPosManager().getMainFrame(), attr);