mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 07:17:13 -04:00
Its possible to edit ram content during operation
This commit is contained in:
parent
0a8afe201b
commit
db5dfdc7c0
@ -3,6 +3,7 @@ package de.neemann.digital.core.memory;
|
|||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,22 +11,26 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
public class DataField {
|
public class DataField {
|
||||||
|
|
||||||
public static final DataField DEFAULT = new DataField(0);
|
public static final DataField DEFAULT = new DataField(0, 8);
|
||||||
|
|
||||||
private final int size;
|
private final int size;
|
||||||
private long[] data;
|
private long[] data;
|
||||||
|
private final int bits;
|
||||||
|
|
||||||
public DataField(int size) {
|
private transient ArrayList<DataListener> listeners;
|
||||||
this(new long[size], size);
|
|
||||||
|
public DataField(int size, int bits) {
|
||||||
|
this(new long[size], size, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataField(long[] data, int size) {
|
private DataField(long[] data, int size, int bits) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.bits = bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataField(DataField dataField, int newSize) {
|
public DataField(DataField dataField, int newSize, int bits) {
|
||||||
this(Arrays.copyOf(dataField.data, newSize), newSize);
|
this(Arrays.copyOf(dataField.data, newSize), newSize, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataField(File file) throws IOException {
|
public DataField(File file) throws IOException {
|
||||||
@ -53,13 +58,18 @@ public class DataField {
|
|||||||
}
|
}
|
||||||
size = pos;
|
size = pos;
|
||||||
}
|
}
|
||||||
|
bits = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(int addr, long value) {
|
public void setData(int addr, long value) {
|
||||||
if (addr < size) {
|
if (addr < size) {
|
||||||
if (addr >= data.length)
|
if (addr >= data.length)
|
||||||
data = Arrays.copyOf(data, size);
|
data = Arrays.copyOf(data, size);
|
||||||
data[addr] = value;
|
|
||||||
|
if (data[addr] != value) {
|
||||||
|
data[addr] = value;
|
||||||
|
fireChanged(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +90,38 @@ public class DataField {
|
|||||||
if (pos == data.length)
|
if (pos == data.length)
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new DataField(Arrays.copyOf(data, pos), size);
|
return new DataField(Arrays.copyOf(data, pos), size, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBits() {
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(DataListener l) {
|
||||||
|
if (listeners == null)
|
||||||
|
listeners = new ArrayList<>();
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(DataListener l) {
|
||||||
|
if (listeners == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
listeners.remove(l);
|
||||||
|
if (listeners.isEmpty())
|
||||||
|
listeners = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fireChanged(int addr) {
|
||||||
|
if (listeners == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (DataListener l : listeners)
|
||||||
|
l.valueChanged(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface DataListener {
|
||||||
|
void valueChanged(int addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,13 @@ import de.neemann.digital.core.element.ElementTypeDescription;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class RAMDualPort extends Node implements Element {
|
public class RAMDualPort extends Node implements Element, RAMInterface {
|
||||||
|
|
||||||
|
|
||||||
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMDualPort.class, "A", "D", "str", "c", "ld")
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMDualPort.class, "A", "D", "str", "c", "ld")
|
||||||
.addAttribute(AttributeKey.Bits)
|
.addAttribute(AttributeKey.Bits)
|
||||||
.addAttribute(AttributeKey.AddrBits)
|
.addAttribute(AttributeKey.AddrBits)
|
||||||
|
.addAttribute(AttributeKey.Label)
|
||||||
.setShortName("RAM");
|
.setShortName("RAM");
|
||||||
|
|
||||||
private final DataField memory;
|
private final DataField memory;
|
||||||
@ -36,7 +37,7 @@ public class RAMDualPort extends Node implements Element {
|
|||||||
bits = attr.get(AttributeKey.Bits);
|
bits = attr.get(AttributeKey.Bits);
|
||||||
output = createOutput();
|
output = createOutput();
|
||||||
addrBits = attr.get(AttributeKey.AddrBits);
|
addrBits = attr.get(AttributeKey.AddrBits);
|
||||||
memory = new DataField(1 << addrBits);
|
memory = new DataField(1 << addrBits, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObservableValue createOutput() {
|
protected ObservableValue createOutput() {
|
||||||
@ -87,4 +88,8 @@ public class RAMDualPort extends Node implements Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataField getMemory() {
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.neemann.digital.core.memory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public interface RAMInterface {
|
||||||
|
DataField getMemory();
|
||||||
|
}
|
@ -11,16 +11,22 @@ import de.neemann.digital.core.element.ElementTypeDescription;
|
|||||||
*/
|
*/
|
||||||
public class RAMSinglePort extends RAMDualPort {
|
public class RAMSinglePort extends RAMDualPort {
|
||||||
|
|
||||||
|
|
||||||
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMSinglePort.class, "A", "str", "c", "ld")
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(RAMSinglePort.class, "A", "str", "c", "ld")
|
||||||
.addAttribute(AttributeKey.Bits)
|
.addAttribute(AttributeKey.Bits)
|
||||||
.addAttribute(AttributeKey.AddrBits)
|
.addAttribute(AttributeKey.AddrBits)
|
||||||
|
.addAttribute(AttributeKey.Label)
|
||||||
.setShortName("RAM");
|
.setShortName("RAM");
|
||||||
|
|
||||||
public RAMSinglePort(ElementAttributes attr) {
|
public RAMSinglePort(ElementAttributes attr) {
|
||||||
super(attr);
|
super(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a port is bidirectional an additional input comes with <code>setInputs</code>.
|
||||||
|
* Using this input you can read back the output port.
|
||||||
|
*
|
||||||
|
* @return outputs
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected ObservableValue createOutput() {
|
protected ObservableValue createOutput() {
|
||||||
return super.createOutput().setBidirectional(true);
|
return super.createOutput().setBidirectional(true);
|
||||||
@ -32,7 +38,7 @@ public class RAMSinglePort extends RAMDualPort {
|
|||||||
strIn = inputs[1].checkBits(1, this).addObserver(this);
|
strIn = inputs[1].checkBits(1, this).addObserver(this);
|
||||||
clkIn = inputs[2].checkBits(1, this).addObserver(this);
|
clkIn = inputs[2].checkBits(1, this).addObserver(this);
|
||||||
ldIn = inputs[3].checkBits(1, this).addObserver(this);
|
ldIn = inputs[3].checkBits(1, this).addObserver(this);
|
||||||
dataIn = inputs[4].checkBits(bits, this).addObserver(this);
|
dataIn = inputs[4].checkBits(bits, this).addObserver(this); // additional input to read the port
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ public class ROM extends Node implements Element {
|
|||||||
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(ROM.class, "A", "sel")
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(ROM.class, "A", "sel")
|
||||||
.addAttribute(AttributeKey.Bits)
|
.addAttribute(AttributeKey.Bits)
|
||||||
.addAttribute(AttributeKey.AddrBits)
|
.addAttribute(AttributeKey.AddrBits)
|
||||||
|
.addAttribute(AttributeKey.Label)
|
||||||
.addAttribute(AttributeKey.Data);
|
.addAttribute(AttributeKey.Data);
|
||||||
|
|
||||||
private final DataField data;
|
private final DataField data;
|
||||||
|
@ -3,6 +3,7 @@ package de.neemann.digital.draw.elements;
|
|||||||
import de.neemann.digital.core.Observer;
|
import de.neemann.digital.core.Observer;
|
||||||
import de.neemann.digital.core.element.AttributeKey;
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
import de.neemann.digital.core.element.AttributeListener;
|
import de.neemann.digital.core.element.AttributeListener;
|
||||||
|
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.draw.graphics.*;
|
import de.neemann.digital.draw.graphics.*;
|
||||||
import de.neemann.digital.draw.shapes.Drawable;
|
import de.neemann.digital.draw.shapes.Drawable;
|
||||||
@ -27,6 +28,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
|
|||||||
private transient IOState ioState;
|
private transient IOState ioState;
|
||||||
private transient Interactor interactor;
|
private transient Interactor interactor;
|
||||||
private transient boolean highLight = false;
|
private transient boolean highLight = false;
|
||||||
|
private transient Element element;
|
||||||
private Vector pos;
|
private Vector pos;
|
||||||
private int rotate;
|
private int rotate;
|
||||||
|
|
||||||
@ -182,7 +184,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
|
|||||||
|
|
||||||
public void clicked(CircuitComponent cc, Point pos) {
|
public void clicked(CircuitComponent cc, Point pos) {
|
||||||
if (interactor != null)
|
if (interactor != null)
|
||||||
interactor.clicked(cc, pos, ioState);
|
interactor.clicked(cc, pos, ioState, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,4 +205,12 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
|
|||||||
else
|
else
|
||||||
return elementName;
|
return elementName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setElement(Element element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,7 +16,6 @@ import java.util.ArrayList;
|
|||||||
public class ModelBuilder {
|
public class ModelBuilder {
|
||||||
|
|
||||||
private final Circuit circuit;
|
private final Circuit circuit;
|
||||||
private boolean bindWiresToGui = true;
|
|
||||||
private boolean disableClock = false;
|
private boolean disableClock = false;
|
||||||
private boolean enableTrace = false;
|
private boolean enableTrace = false;
|
||||||
private ModelDescription modelDescription;
|
private ModelDescription modelDescription;
|
||||||
@ -25,11 +24,6 @@ public class ModelBuilder {
|
|||||||
this.circuit = circuit;
|
this.circuit = circuit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelBuilder setBindWiresToGui(boolean bindWiresToGui) {
|
|
||||||
this.bindWiresToGui = bindWiresToGui;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModelBuilder setDisableClock(boolean disableClock) {
|
public ModelBuilder setDisableClock(boolean disableClock) {
|
||||||
this.disableClock = disableClock;
|
this.disableClock = disableClock;
|
||||||
return this;
|
return this;
|
||||||
@ -42,7 +36,7 @@ public class ModelBuilder {
|
|||||||
|
|
||||||
public Model build(ElementLibrary library) throws PinException, NodeException {
|
public Model build(ElementLibrary library) throws PinException, NodeException {
|
||||||
modelDescription = new ModelDescription(circuit, library);
|
modelDescription = new ModelDescription(circuit, library);
|
||||||
Model model = modelDescription.createModel(bindWiresToGui);
|
Model model = modelDescription.createModel();
|
||||||
|
|
||||||
if (enableTrace) {
|
if (enableTrace) {
|
||||||
|
|
||||||
|
@ -49,10 +49,11 @@ public class ModelDescription implements Iterable<ModelEntry> {
|
|||||||
else
|
else
|
||||||
ioMap = null;
|
ioMap = null;
|
||||||
|
|
||||||
for (VisualElement vp : circuit.getElements()) {
|
for (VisualElement ve : circuit.getElements()) {
|
||||||
Pins pins = vp.getPins();
|
Pins pins = ve.getPins();
|
||||||
ElementTypeDescription elementType = library.getElementType(vp.getElementName());
|
ElementTypeDescription elementType = library.getElementType(ve.getElementName());
|
||||||
Element element = elementType.createElement(vp.getElementAttributes());
|
Element element = elementType.createElement(ve.getElementAttributes());
|
||||||
|
ve.setElement(element);
|
||||||
pins.bindOutputsToOutputPins(element.getOutputs());
|
pins.bindOutputsToOutputPins(element.getOutputs());
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ public class ModelDescription implements Iterable<ModelEntry> {
|
|||||||
boolean isNotAIO = true;
|
boolean isNotAIO = true;
|
||||||
if (readAsCustom) {
|
if (readAsCustom) {
|
||||||
if (elementType == In.DESCRIPTION || elementType == Out.DESCRIPTION) {
|
if (elementType == In.DESCRIPTION || elementType == Out.DESCRIPTION) {
|
||||||
String label = vp.getElementAttributes().get(AttributeKey.Label);
|
String label = ve.getElementAttributes().get(AttributeKey.Label);
|
||||||
if (label == null || label.length() == 0)
|
if (label == null || label.length() == 0)
|
||||||
throw new PinException(Lang.get("err_pinWithoutName"));
|
throw new PinException(Lang.get("err_pinWithoutName"));
|
||||||
if (pins.size() != 1)
|
if (pins.size() != 1)
|
||||||
@ -72,7 +73,7 @@ public class ModelDescription implements Iterable<ModelEntry> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isNotAIO)
|
if (isNotAIO)
|
||||||
entries.add(new ModelEntry(element, pins, vp, elementType.getInputNames(vp.getElementAttributes())));
|
entries.add(new ModelEntry(element, pins, ve, elementType.getInputNames(ve.getElementAttributes())));
|
||||||
|
|
||||||
for (Pin p : pins)
|
for (Pin p : pins)
|
||||||
netList.add(p);
|
netList.add(p);
|
||||||
@ -129,14 +130,13 @@ public class ModelDescription implements Iterable<ModelEntry> {
|
|||||||
/**
|
/**
|
||||||
* Creates the model
|
* Creates the model
|
||||||
*
|
*
|
||||||
* @param bindWiresToValues
|
|
||||||
* @return the model
|
* @return the model
|
||||||
* @throws PinException
|
* @throws PinException
|
||||||
* @throws NodeException
|
* @throws NodeException
|
||||||
*/
|
*/
|
||||||
public Model createModel(boolean bindWiresToValues) throws PinException, NodeException {
|
public Model createModel() throws PinException, NodeException {
|
||||||
for (Net n : netList)
|
for (Net n : netList)
|
||||||
n.interconnect(bindWiresToValues);
|
n.interconnect();
|
||||||
|
|
||||||
Model m = new Model();
|
Model m = new Model();
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public class Net {
|
|||||||
pins.addAll(p);
|
pins.addAll(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void interconnect(boolean bindWiresToValues) throws PinException {
|
public void interconnect() throws PinException {
|
||||||
ArrayList<Pin> inputs = new ArrayList<>();
|
ArrayList<Pin> inputs = new ArrayList<>();
|
||||||
ArrayList<Pin> outputs = new ArrayList<>();
|
ArrayList<Pin> outputs = new ArrayList<>();
|
||||||
for (Pin p : pins) {
|
for (Pin p : pins) {
|
||||||
@ -100,7 +100,7 @@ public class Net {
|
|||||||
for (Pin o : outputs) // set also the reader for bidirectional pins
|
for (Pin o : outputs) // set also the reader for bidirectional pins
|
||||||
o.setReaderValue(value);
|
o.setReaderValue(value);
|
||||||
|
|
||||||
if (bindWiresToValues && wires != null)
|
if (wires != null)
|
||||||
for (Wire w : wires)
|
for (Wire w : wires)
|
||||||
w.setValue(value);
|
w.setValue(value);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package de.neemann.digital.draw.shapes;
|
|||||||
|
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.core.Observer;
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
import de.neemann.digital.draw.elements.IOState;
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
import de.neemann.digital.draw.elements.Pin;
|
import de.neemann.digital.draw.elements.Pin;
|
||||||
import de.neemann.digital.draw.elements.Pins;
|
import de.neemann.digital.draw.elements.Pins;
|
||||||
@ -34,7 +35,7 @@ public class ClockShape implements Shape {
|
|||||||
ioState.getOutput(0).addObserver(guiObserver); // necessary to replot wires also if component itself does not depend on state
|
ioState.getOutput(0).addObserver(guiObserver); // necessary to replot wires also if component itself does not depend on state
|
||||||
return new Interactor() {
|
return new Interactor() {
|
||||||
@Override
|
@Override
|
||||||
public void clicked(CircuitComponent cc, Point pos, IOState ioState) {
|
public void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
ObservableValue value = ioState.getOutput(0);
|
ObservableValue value = ioState.getOutput(0);
|
||||||
if (value.getBits() == 1) {
|
if (value.getBits() == 1) {
|
||||||
value.setValue(1 - value.getValue());
|
value.setValue(1 - value.getValue());
|
||||||
|
@ -2,6 +2,7 @@ package de.neemann.digital.draw.shapes;
|
|||||||
|
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.core.Observer;
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
import de.neemann.digital.draw.elements.IOState;
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
import de.neemann.digital.draw.elements.Pin;
|
import de.neemann.digital.draw.elements.Pin;
|
||||||
import de.neemann.digital.draw.elements.Pins;
|
import de.neemann.digital.draw.elements.Pins;
|
||||||
@ -38,7 +39,7 @@ public class InputShape implements Shape {
|
|||||||
ioState.getOutput(0).addObserver(guiObserver);
|
ioState.getOutput(0).addObserver(guiObserver);
|
||||||
return new Interactor() {
|
return new Interactor() {
|
||||||
@Override
|
@Override
|
||||||
public void clicked(CircuitComponent cc, Point pos, IOState ioState) {
|
public void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
ObservableValue value = ioState.getOutput(0);
|
ObservableValue value = ioState.getOutput(0);
|
||||||
if (value.getBits() == 1) {
|
if (value.getBits() == 1) {
|
||||||
value.setValue(1 - value.getValue());
|
value.setValue(1 - value.getValue());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.draw.shapes;
|
package de.neemann.digital.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
import de.neemann.digital.draw.elements.IOState;
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
import de.neemann.digital.gui.components.CircuitComponent;
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
|
||||||
@ -22,5 +23,5 @@ public interface Interactor {
|
|||||||
* @param pos the popuplocation on screen
|
* @param pos the popuplocation on screen
|
||||||
* @param ioState the state of the element
|
* @param ioState the state of the element
|
||||||
*/
|
*/
|
||||||
void clicked(CircuitComponent cc, Point pos, IOState ioState);
|
void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element);
|
||||||
}
|
}
|
||||||
|
33
src/main/java/de/neemann/digital/draw/shapes/RAMShape.java
Normal file
33
src/main/java/de/neemann/digital/draw/shapes/RAMShape.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package de.neemann.digital.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
|
import de.neemann.digital.core.memory.DataField;
|
||||||
|
import de.neemann.digital.core.memory.RAMInterface;
|
||||||
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
import de.neemann.digital.gui.components.DataEditor;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class RAMShape extends GenericShape {
|
||||||
|
public RAMShape(String name, String[] inputs, OutputPinInfo[] outputs, String label) {
|
||||||
|
super(name, inputs, outputs, label, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
|
return new Interactor() {
|
||||||
|
@Override
|
||||||
|
public void clicked(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
|
if (element instanceof RAMInterface) {
|
||||||
|
DataField dataField = ((RAMInterface) element).getMemory();
|
||||||
|
new DataEditor(cc, dataField).showDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,8 @@ import de.neemann.digital.core.element.ElementTypeDescription;
|
|||||||
import de.neemann.digital.core.io.Const;
|
import de.neemann.digital.core.io.Const;
|
||||||
import de.neemann.digital.core.io.In;
|
import de.neemann.digital.core.io.In;
|
||||||
import de.neemann.digital.core.io.Out;
|
import de.neemann.digital.core.io.Out;
|
||||||
|
import de.neemann.digital.core.memory.RAMDualPort;
|
||||||
|
import de.neemann.digital.core.memory.RAMSinglePort;
|
||||||
import de.neemann.digital.core.wiring.*;
|
import de.neemann.digital.core.wiring.*;
|
||||||
import de.neemann.digital.draw.library.ElementLibrary;
|
import de.neemann.digital.draw.library.ElementLibrary;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
@ -49,6 +51,8 @@ public final class ShapeFactory {
|
|||||||
map.put(Sub.DESCRIPTION.getName(), attr -> new GenericShape("-", Sub.DESCRIPTION.getInputNames(attr), outputInfos(Sub.DESCRIPTION, attr), null, true));
|
map.put(Sub.DESCRIPTION.getName(), attr -> new GenericShape("-", Sub.DESCRIPTION.getInputNames(attr), outputInfos(Sub.DESCRIPTION, attr), null, true));
|
||||||
map.put(Mul.DESCRIPTION.getName(), attr -> new GenericShape("*", Mul.DESCRIPTION.getInputNames(attr), outputInfos(Mul.DESCRIPTION, attr), null, true));
|
map.put(Mul.DESCRIPTION.getName(), attr -> new GenericShape("*", Mul.DESCRIPTION.getInputNames(attr), outputInfos(Mul.DESCRIPTION, attr), null, true));
|
||||||
|
|
||||||
|
map.put(RAMDualPort.DESCRIPTION.getName(), attr -> new RAMShape("RAM", RAMDualPort.DESCRIPTION.getInputNames(attr), outputInfos(RAMDualPort.DESCRIPTION, attr), attr.get(AttributeKey.Label)));
|
||||||
|
map.put(RAMSinglePort.DESCRIPTION.getName(), attr -> new RAMShape("RAM", RAMSinglePort.DESCRIPTION.getInputNames(attr), outputInfos(RAMSinglePort.DESCRIPTION, attr), attr.get(AttributeKey.Label)));
|
||||||
|
|
||||||
map.put(In.DESCRIPTION.getName(), attr -> new InputShape(attr.get(AttributeKey.Label)));
|
map.put(In.DESCRIPTION.getName(), attr -> new InputShape(attr.get(AttributeKey.Label)));
|
||||||
map.put(Const.DESCRIPTION.getName(), attr -> new ConstShape(attr.get(AttributeKey.Value)));
|
map.put(Const.DESCRIPTION.getName(), attr -> new ConstShape(attr.get(AttributeKey.Value)));
|
||||||
|
@ -56,7 +56,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
|||||||
super(Lang.get("digital"));
|
super(Lang.get("digital"));
|
||||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
|
|
||||||
Circuit cr = new Circuit();
|
Circuit cr = new Circuit();
|
||||||
circuitComponent = new CircuitComponent(cr, library);
|
circuitComponent = new CircuitComponent(cr, library);
|
||||||
String name = prefs.get("name", null);
|
String name = prefs.get("name", null);
|
||||||
@ -195,7 +194,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
try {
|
try {
|
||||||
Model model = new ModelBuilder(circuitComponent.getCircuit())
|
Model model = new ModelBuilder(circuitComponent.getCircuit())
|
||||||
.setBindWiresToGui(false)
|
|
||||||
.build(library);
|
.build(library);
|
||||||
|
|
||||||
SpeedTest speedTest = new SpeedTest(model);
|
SpeedTest speedTest = new SpeedTest(model);
|
||||||
@ -255,7 +253,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
|||||||
circuitComponent.setModeAndReset(CircuitComponent.Mode.running);
|
circuitComponent.setModeAndReset(CircuitComponent.Mode.running);
|
||||||
|
|
||||||
mb = new ModelBuilder(circuitComponent.getCircuit())
|
mb = new ModelBuilder(circuitComponent.getCircuit())
|
||||||
.setBindWiresToGui(true)
|
|
||||||
.setDisableClock(!runClock)
|
.setDisableClock(!runClock)
|
||||||
.setEnableTrace(traceEnable.isSelected(), Main.this);
|
.setEnableTrace(traceEnable.isSelected(), Main.this);
|
||||||
|
|
||||||
|
@ -6,11 +6,14 @@ import de.neemann.digital.core.memory.DataField;
|
|||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.TableModelEvent;
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,26 +23,54 @@ public class DataEditor extends JDialog {
|
|||||||
private final DataField dataField;
|
private final DataField dataField;
|
||||||
private boolean ok = false;
|
private boolean ok = false;
|
||||||
|
|
||||||
|
public DataEditor(JComponent parent, DataField dataField) {
|
||||||
|
this(parent, dataField, null);
|
||||||
|
}
|
||||||
|
|
||||||
public DataEditor(JComponent parent, DataField dataField, ElementAttributes attr) {
|
public DataEditor(JComponent parent, DataField dataField, ElementAttributes attr) {
|
||||||
super(SwingUtilities.windowForComponent(parent), Lang.get("key_data"), ModalityType.APPLICATION_MODAL);
|
super(SwingUtilities.windowForComponent(parent), Lang.get("key_data"), attr == null ? ModalityType.MODELESS : ModalityType.APPLICATION_MODAL);
|
||||||
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
int bits = attr.getBits();
|
|
||||||
int size;
|
int size;
|
||||||
if (attr.contains(AttributeKey.AddrBits))
|
int bits;
|
||||||
size = 1 << attr.get(AttributeKey.AddrBits);
|
boolean register;
|
||||||
else
|
if (attr != null) {
|
||||||
size = 1 << attr.get(AttributeKey.InputCount);
|
bits = attr.getBits();
|
||||||
|
if (attr.contains(AttributeKey.AddrBits))
|
||||||
|
size = 1 << attr.get(AttributeKey.AddrBits);
|
||||||
|
else
|
||||||
|
size = 1 << attr.get(AttributeKey.InputCount);
|
||||||
|
|
||||||
this.dataField = new DataField(dataField, size);
|
this.dataField = new DataField(dataField, size, bits);
|
||||||
|
register = false;
|
||||||
|
} else {
|
||||||
|
this.dataField = dataField;
|
||||||
|
size = this.dataField.size();
|
||||||
|
bits = this.dataField.getBits();
|
||||||
|
register = true;
|
||||||
|
}
|
||||||
|
|
||||||
int cols = 16;
|
int cols = 16;
|
||||||
if (size <= 16) cols = 1;
|
if (size <= 16) cols = 1;
|
||||||
else if (size <= 128) cols = 8;
|
else if (size <= 128) cols = 8;
|
||||||
|
|
||||||
JTable table = new JTable(new MyTableModel(this.dataField, cols));
|
MyTableModel dm = new MyTableModel(this.dataField, cols);
|
||||||
|
JTable table = new JTable(dm);
|
||||||
table.setDefaultRenderer(MyLong.class, new MyLongRenderer(bits));
|
table.setDefaultRenderer(MyLong.class, new MyLongRenderer(bits));
|
||||||
getContentPane().add(new JScrollPane(table));
|
getContentPane().add(new JScrollPane(table));
|
||||||
|
|
||||||
|
if (register) {
|
||||||
|
this.dataField.addListener(dm);
|
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
DataEditor.this.dataField.removeListener(dm);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||||
buttons.add(new JButton(new AbstractAction(Lang.get("ok")) {
|
buttons.add(new JButton(new AbstractAction(Lang.get("ok")) {
|
||||||
@Override
|
@Override
|
||||||
@ -50,7 +81,10 @@ public class DataEditor extends JDialog {
|
|||||||
}));
|
}));
|
||||||
getContentPane().add(buttons, BorderLayout.SOUTH);
|
getContentPane().add(buttons, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
setPreferredSize(new Dimension((cols + 1) * 50, getPreferredSize().height));
|
||||||
|
|
||||||
pack();
|
pack();
|
||||||
|
|
||||||
setLocationRelativeTo(parent);
|
setLocationRelativeTo(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +97,7 @@ public class DataEditor extends JDialog {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MyTableModel implements TableModel {
|
private class MyTableModel implements TableModel, DataField.DataListener {
|
||||||
private final DataField dataField;
|
private final DataField dataField;
|
||||||
private final int cols;
|
private final int cols;
|
||||||
private final int rows;
|
private final int rows;
|
||||||
@ -118,6 +152,11 @@ public class DataEditor extends JDialog {
|
|||||||
dataField.setData(rowIndex * cols + (columnIndex - 1), ((MyLong) aValue).getValue());
|
dataField.setData(rowIndex * cols + (columnIndex - 1), ((MyLong) aValue).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fireEvent(TableModelEvent e) {
|
||||||
|
for (TableModelListener l : listener)
|
||||||
|
l.tableChanged(e);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addTableModelListener(TableModelListener l) {
|
public void addTableModelListener(TableModelListener l) {
|
||||||
listener.add(l);
|
listener.add(l);
|
||||||
@ -127,6 +166,11 @@ public class DataEditor extends JDialog {
|
|||||||
public void removeTableModelListener(TableModelListener l) {
|
public void removeTableModelListener(TableModelListener l) {
|
||||||
listener.remove(l);
|
listener.remove(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged(int addr) {
|
||||||
|
fireEvent(new TableModelEvent(this, addr / cols));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import java.io.StringReader;
|
|||||||
public class DataFieldTest extends TestCase {
|
public class DataFieldTest extends TestCase {
|
||||||
|
|
||||||
public void testGetMinimized() throws Exception {
|
public void testGetMinimized() throws Exception {
|
||||||
DataField data = new DataField(100);
|
DataField data = new DataField(100, 8);
|
||||||
data.setData(9, 1);
|
data.setData(9, 1);
|
||||||
data = data.getMinimized();
|
data = data.getMinimized();
|
||||||
assertEquals(1, data.getData(9));
|
assertEquals(1, data.getData(9));
|
||||||
@ -19,7 +19,7 @@ public class DataFieldTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testGrow() throws Exception {
|
public void testGrow() throws Exception {
|
||||||
DataField data = new DataField(100);
|
DataField data = new DataField(100, 8);
|
||||||
data.setData(9, 1);
|
data.setData(9, 1);
|
||||||
data = data.getMinimized();
|
data = data.getMinimized();
|
||||||
assertEquals(1, data.getData(9));
|
assertEquals(1, data.getData(9));
|
||||||
|
@ -18,7 +18,7 @@ public class LUTTest extends TestCase {
|
|||||||
ObservableValue c = new ObservableValue("c", 1);
|
ObservableValue c = new ObservableValue("c", 1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
DataField data = new DataField(8);
|
DataField data = new DataField(8, 8);
|
||||||
data.setData(3, 1);
|
data.setData(3, 1);
|
||||||
data.setData(7, 1);
|
data.setData(7, 1);
|
||||||
LookUpTable out = model.add(new LookUpTable(
|
LookUpTable out = model.add(new LookUpTable(
|
||||||
|
@ -18,7 +18,7 @@ public class ROMTest extends TestCase {
|
|||||||
ObservableValue sel = new ObservableValue("sel", 1);
|
ObservableValue sel = new ObservableValue("sel", 1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
DataField data = new DataField(8);
|
DataField data = new DataField(8, 8);
|
||||||
data.setData(3, 17);
|
data.setData(3, 17);
|
||||||
data.setData(7, 200);
|
data.setData(7, 200);
|
||||||
ROM out = model.add(new ROM(
|
ROM out = model.add(new ROM(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user