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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
boolean write = cs && we;
|
||||
if (write && !lastWrite)
|
||||
writeAddr = (int) addrIn.getValue();
|
||||
|
||||
if (!write && lastWrite) {
|
||||
if (we) {
|
||||
long data = dataIn.getValue();
|
||||
memory.setData(writeAddr, data);
|
||||
memory.setData(addr, 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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user