Export-Package: net.mograsim.logic.core,
net.mograsim.logic.core.components,
net.mograsim.logic.core.components.gates,
- net.mograsim.logic.core.components.memory,
net.mograsim.logic.core.timeline,
net.mograsim.logic.core.types,
net.mograsim.logic.core.wires
+++ /dev/null
-package net.mograsim.logic.core.components.memory;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-
-public class WordAddressableMemory
-{
- private final int cellWidth;
- private final long minimalAddress, maximalAddress;
- private final int pageSize = 64;
-
- private HashMap<Long, Page> pages;
-
- public WordAddressableMemory(int cellWidth, long minimalAddress, long maximalAddress)
- {
- super();
- this.cellWidth = cellWidth;
- this.minimalAddress = minimalAddress;
- this.maximalAddress = maximalAddress;
- this.pages = new HashMap<>();
- }
-
- public void setCell(long address, BitVector b)
- {
- if (address < minimalAddress || address > maximalAddress)
- throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
- minimalAddress, maximalAddress, address));
- long page = address / pageSize;
- int offset = (int) (address % pageSize);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- pages.put(page, p = new Page());
- p.setCell(offset, b);
- }
-
- public BitVector getCell(long address)
- {
- long page = address / pageSize;
- int offset = (int) (address % pageSize);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- return BitVector.of(Bit.U, cellWidth);
- return p.getCell(offset);
- }
-
- private class Page
- {
- private BitVector[] memory;
-
- public Page()
- {
- memory = new BitVector[pageSize];
- }
-
- public BitVector getCell(int index)
- {
- BitVector b = memory[index];
- if (b == null)
- return BitVector.of(Bit.U, cellWidth);
- return memory[index];
- }
-
- public void setCell(int index, BitVector bits)
- {
- if (bits.length() != cellWidth)
- throw new IllegalArgumentException(String.format(
- "BitVector to be saved in memory cell has unexpected length. Expected: %d Actual: %d", cellWidth, bits.length()));
- memory[index] = bits;
- }
-
- @Override
- public String toString()
- {
- return Arrays.deepToString(memory);
- }
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.memory;
-
-import java.util.List;
-
-import net.mograsim.logic.core.components.BasicComponent;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-/**
- * A memory component that only allows access to words of a specific length
- */
-public class WordAddressableMemoryComponent extends BasicComponent
-{
- private final WordAddressableMemory memory;
- private final static Bit read = Bit.ONE;
-
- private ReadWriteEnd data;
- private ReadEnd rWBit, address;
-
- /**
- * @param data The bits of this ReadEnd are the value that is written to/read from memory; The bit width of this wire is the width of
- * a memory word
- * @param rWBit The value of the 0th bit dictates the mode: 0: Write, 1: Read
- * @param address The bits of this ReadEnd address the memory cell to read/write
- */
- public WordAddressableMemoryComponent(Timeline timeline, int processTime, long minimalAddress, long maximalAddress, ReadWriteEnd data,
- ReadEnd rWBit, ReadEnd address)
- {
- super(timeline, processTime);
- this.data = data;
- this.rWBit = rWBit;
- this.address = address;
- data.registerObserver(this);
- rWBit.registerObserver(this);
- address.registerObserver(this);
-
- memory = new WordAddressableMemory(data.length(), minimalAddress, maximalAddress);
- }
-
- @Override
- protected void compute()
- {
- if (!address.hasNumericValue())
- {
- if (read.equals(rWBit.getValue()))
- data.feedSignals(BitVector.of(Bit.U, data.length()));
- else
- data.clearSignals();
- return;
- }
- long addressed = address.getUnsignedValue();
- if (read.equals(rWBit.getValue()))
- data.feedSignals(memory.getCell(addressed));
- else
- {
- data.clearSignals();
- memory.setCell(addressed, data.getValues());
- }
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(data, rWBit, address);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(data);
- }
-}
\ No newline at end of file
import net.mograsim.logic.core.components.gates.NotGate;\r
import net.mograsim.logic.core.components.gates.OrGate;\r
import net.mograsim.logic.core.components.gates.XorGate;\r
-import net.mograsim.logic.core.components.memory.WordAddressableMemoryComponent;\r
import net.mograsim.logic.core.timeline.Timeline;\r
import net.mograsim.logic.core.types.Bit;\r
import net.mograsim.logic.core.types.BitVector;\r
test2.assertAfterSimulationIs(Bit.ONE);\r
}\r
\r
- @Test\r
- public void wordAddressableMemoryLargeTest()\r
- {\r
- Wire rW = new Wire(t, 1, 2);\r
- Wire data = new Wire(t, 16, 2);\r
- Wire address = new Wire(t, 64, 2);\r
- ReadWriteEnd rWI = rW.createReadWriteEnd();\r
- ReadWriteEnd dataI = data.createReadWriteEnd();\r
- ReadWriteEnd addressI = address.createReadWriteEnd();\r
-\r
- WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, 4096L, Long.MAX_VALUE, data.createReadWriteEnd(),\r
- rW.createReadOnlyEnd(), address.createReadOnlyEnd());\r
-\r
- Random r = new Random();\r
- for (long j = 1; j > 0; j *= 2)\r
- {\r
- for (int i = 0; i < 50; i++)\r
- {\r
- String sAddress = String.format("%64s", BigInteger.valueOf(4096 + i + j).toString(2)).replace(' ', '0');\r
- sAddress = new StringBuilder(sAddress).reverse().toString();\r
- BitVector bAddress = BitVector.parse(sAddress);\r
- addressI.feedSignals(bAddress);\r
- t.executeAll();\r
- String random = BigInteger.valueOf(Math.abs(r.nextInt())).toString(5);\r
- random = random.substring(Integer.max(0, random.length() - 16));\r
- random = String.format("%16s", random).replace(' ', '0');\r
- random = random.replace('2', 'X').replace('3', 'Z').replace('4', 'U');\r
- BitVector vector = BitVector.parse(random);\r
- dataI.feedSignals(vector);\r
- rWI.feedSignals(Bit.ZERO);\r
- t.executeAll();\r
- rWI.feedSignals(Bit.ONE);\r
- t.executeAll();\r
- dataI.clearSignals();\r
- t.executeAll();\r
-\r
- assertBitArrayEquals(dataI.getValues(), vector.getBits());\r
- }\r
- }\r
- }\r
-\r
private static void assertBitArrayEquals(BitVector actual, Bit... expected)\r
{\r
assertArrayEquals(expected, actual.getBits());\r
+++ /dev/null
-package net.mograsim.logic.model.model.components.atomic;
-
-import org.eclipse.swt.graphics.Color;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.model.model.ViewModelModifiable;
-import net.mograsim.logic.model.model.components.GUIComponent;
-import net.mograsim.logic.model.model.wires.Pin;
-import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.model.modeladapter.componentadapters.WordAddressableMemoryAdapter;
-import net.mograsim.logic.model.serializing.IdentifierGetter;
-import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
-import net.mograsim.preferences.Preferences;
-
-public class GUIMemoryWA extends GUIComponent
-{
- private final static String paramAddr = "addrBits", paramWordWidth = "wordWidth", paramMaxAddr = "maxAddr", paramMinAddr = "minAddr";
- private final int addressBits, wordWidth;
- public final long maximalAddress, minimalAddress;
- private final Pin addrPin, dataPin, rWPin;
- private final static int width = 100, height = 300;
-
- public GUIMemoryWA(ViewModelModifiable model, int addressBits, int wordWidth, long maximalAddress, long minimalAddress, String name)
- {
- super(model, name);
- this.addressBits = addressBits;
- this.wordWidth = wordWidth;
- this.maximalAddress = maximalAddress;
- this.minimalAddress = minimalAddress;
- setSize(width, height);
- addPin(addrPin = new Pin(this, "A", addressBits, 0, 10));
- addPin(dataPin = new Pin(this, "D", wordWidth, 0, 30));
- addPin(rWPin = new Pin(this, "RW", 1, 0, 50));
- }
-
- public Pin getAddressPin()
- {
- return addrPin;
- }
-
- public Pin getDataPin()
- {
- return dataPin;
- }
-
- public Pin getReadWritePin()
- {
- return rWPin;
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- // TODO This is copied from SimpleRectangularGUIGate; do this via delegation instead
- Color foreground = Preferences.current().getColor("net.mograsim.logic.model.color.foreground");
- if (foreground != null)
- gc.setForeground(foreground);
- gc.drawRectangle(getPosX(), getPosY(), width, height);
- Font oldFont = gc.getFont();
- Font labelFont = new Font(oldFont.getName(), 24, oldFont.getStyle());
- gc.setFont(labelFont);
- String label = "RAM";
- Point textExtent = gc.textExtent(label);
- Color textColor = Preferences.current().getColor("net.mograsim.logic.model.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
- gc.setFont(oldFont);
- }
-
- @Override
- public JsonElement getParamsForSerializing(IdentifierGetter idGetter)
- {
- JsonObject obj = new JsonObject();
- obj.addProperty(paramAddr, addressBits);
- obj.addProperty(paramWordWidth, wordWidth);
- obj.addProperty(paramMaxAddr, maximalAddress);
- obj.addProperty(paramMinAddr, minimalAddress);
- return obj;
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new WordAddressableMemoryAdapter());
- IndirectGUIComponentCreator.setComponentSupplier(GUIAndGate.class.getCanonicalName(), (m, p, n) ->
- {
- JsonObject obj = p.getAsJsonObject();
- return new GUIMemoryWA(m, obj.get(paramAddr).getAsInt(), obj.get(paramWordWidth).getAsInt(), obj.get(paramMaxAddr).getAsLong(),
- obj.get(paramMinAddr).getAsLong(), n);
- });
- }
-}
+++ /dev/null
-package net.mograsim.logic.model.modeladapter.componentadapters;
-
-import java.util.Map;
-
-import net.mograsim.logic.core.components.memory.WordAddressableMemoryComponent;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-import net.mograsim.logic.model.model.components.atomic.GUIMemoryWA;
-import net.mograsim.logic.model.model.wires.Pin;
-import net.mograsim.logic.model.modeladapter.LogicModelParameters;
-
-public class WordAddressableMemoryAdapter implements ComponentAdapter<GUIMemoryWA>
-{
-
- @Override
- public Class<GUIMemoryWA> getSupportedClass()
- {
- return GUIMemoryWA.class;
- }
-
- @SuppressWarnings("unused")
- @Override
- public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIMemoryWA guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
- {
- ReadWriteEnd data = logicWiresPerPin.get(guiComponent.getDataPin()).createReadWriteEnd();
- ReadEnd address = logicWiresPerPin.get(guiComponent.getAddressPin()).createReadOnlyEnd();
- ReadEnd mode = logicWiresPerPin.get(guiComponent.getReadWritePin()).createReadOnlyEnd();
- new WordAddressableMemoryComponent(timeline, 2, guiComponent.maximalAddress, guiComponent.minimalAddress, data, mode, address);
- }
-
-}
<?xml version="1.0" encoding="UTF-8"?>\r
<classpath>\r
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>\r
+ <classpathentry kind="src" output="bin/src" path="src"/>\r
+ <classpathentry kind="src" output="bin/test" path="test">\r
+ <attributes>\r
+ <attribute name="test" value="true"/>\r
+ </attributes>\r
+ </classpathentry>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">\r
+ <attributes>\r
+ <attribute name="module" value="true"/>\r
+ </attributes>\r
+ </classpathentry>\r
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
- <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>\r
<classpathentry kind="output" path="bin"/>\r
</classpath>\r
Automatic-Module-Name: net.mograsim.machine
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: net.mograsim.logic.core;bundle-version="0.1.0",
- net.mograsim.logic.model;bundle-version="0.1.0"
-Export-Package: net.mograsim.machine.isa
+ net.mograsim.logic.model;bundle-version="0.1.0",
+ net.mograsim.preferences
+Export-Package: net.mograsim.machine,
+ net.mograsim.machine.isa,
+ net.mograsim.machine.isa.types,
+ net.mograsim.machine.standard.memory
--- /dev/null
+package net.mograsim.machine.standard.memory;
+
+import org.eclipse.swt.graphics.Color;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.model.model.ViewModelModifiable;
+import net.mograsim.logic.model.model.components.GUIComponent;
+import net.mograsim.logic.model.model.components.atomic.GUIAndGate;
+import net.mograsim.logic.model.model.wires.Pin;
+import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.model.serializing.IdentifierGetter;
+import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
+import net.mograsim.preferences.Preferences;
+
+public class GUIMemoryWA extends GUIComponent
+{
+ private final static String paramAddr = "addrBits", paramWordWidth = "wordWidth", paramMaxAddr = "maxAddr", paramMinAddr = "minAddr";
+ private final int addressBits, wordWidth;
+ public final long maximalAddress, minimalAddress;
+ private final Pin addrPin, dataPin, rWPin;
+ private final static int width = 100, height = 300;
+
+ public GUIMemoryWA(ViewModelModifiable model, int addressBits, int wordWidth, long maximalAddress, long minimalAddress, String name)
+ {
+ super(model, name);
+ this.addressBits = addressBits;
+ this.wordWidth = wordWidth;
+ this.maximalAddress = maximalAddress;
+ this.minimalAddress = minimalAddress;
+ setSize(width, height);
+ addPin(addrPin = new Pin(this, "A", addressBits, 0, 10));
+ addPin(dataPin = new Pin(this, "D", wordWidth, 0, 30));
+ addPin(rWPin = new Pin(this, "RW", 1, 0, 50));
+ }
+
+ public Pin getAddressPin()
+ {
+ return addrPin;
+ }
+
+ public Pin getDataPin()
+ {
+ return dataPin;
+ }
+
+ public Pin getReadWritePin()
+ {
+ return rWPin;
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ // TODO This is copied from SimpleRectangularGUIGate; do this via delegation instead
+ Color foreground = Preferences.current().getColor("net.mograsim.logic.model.color.foreground");
+ if (foreground != null)
+ gc.setForeground(foreground);
+ gc.drawRectangle(getPosX(), getPosY(), width, height);
+ Font oldFont = gc.getFont();
+ Font labelFont = new Font(oldFont.getName(), 24, oldFont.getStyle());
+ gc.setFont(labelFont);
+ String label = "RAM";
+ Point textExtent = gc.textExtent(label);
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.model.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
+ gc.setFont(oldFont);
+ }
+
+ @Override
+ public JsonElement getParamsForSerializing(IdentifierGetter idGetter)
+ {
+ JsonObject obj = new JsonObject();
+ obj.addProperty(paramAddr, addressBits);
+ obj.addProperty(paramWordWidth, wordWidth);
+ obj.addProperty(paramMaxAddr, maximalAddress);
+ obj.addProperty(paramMinAddr, minimalAddress);
+ return obj;
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new WordAddressableMemoryAdapter());
+ IndirectGUIComponentCreator.setComponentSupplier(GUIAndGate.class.getCanonicalName(), (m, p, n) ->
+ {
+ JsonObject obj = p.getAsJsonObject();
+ return new GUIMemoryWA(m, obj.get(paramAddr).getAsInt(), obj.get(paramWordWidth).getAsInt(), obj.get(paramMaxAddr).getAsLong(),
+ obj.get(paramMinAddr).getAsLong(), n);
+ });
+ }
+}
--- /dev/null
+package net.mograsim.machine.standard.memory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+
+public class WordAddressableMemory
+{
+ private final int cellWidth;
+ private final long minimalAddress, maximalAddress;
+ private final int pageSize = 64;
+
+ private HashMap<Long, Page> pages;
+
+ public WordAddressableMemory(int cellWidth, long minimalAddress, long maximalAddress)
+ {
+ super();
+ this.cellWidth = cellWidth;
+ this.minimalAddress = minimalAddress;
+ this.maximalAddress = maximalAddress;
+ this.pages = new HashMap<>();
+ }
+
+ public void setCell(long address, BitVector b)
+ {
+ if (address < minimalAddress || address > maximalAddress)
+ throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
+ minimalAddress, maximalAddress, address));
+ long page = address / pageSize;
+ int offset = (int) (address % pageSize);
+ Page p = pages.get(Long.valueOf(page));
+ if (p == null)
+ pages.put(page, p = new Page());
+ p.setCell(offset, b);
+ }
+
+ public BitVector getCell(long address)
+ {
+ long page = address / pageSize;
+ int offset = (int) (address % pageSize);
+ Page p = pages.get(Long.valueOf(page));
+ if (p == null)
+ return BitVector.of(Bit.U, cellWidth);
+ return p.getCell(offset);
+ }
+
+ private class Page
+ {
+ private BitVector[] memory;
+
+ public Page()
+ {
+ memory = new BitVector[pageSize];
+ }
+
+ public BitVector getCell(int index)
+ {
+ BitVector b = memory[index];
+ if (b == null)
+ return BitVector.of(Bit.U, cellWidth);
+ return memory[index];
+ }
+
+ public void setCell(int index, BitVector bits)
+ {
+ if (bits.length() != cellWidth)
+ throw new IllegalArgumentException(String.format(
+ "BitVector to be saved in memory cell has unexpected length. Expected: %d Actual: %d", cellWidth, bits.length()));
+ memory[index] = bits;
+ }
+
+ @Override
+ public String toString()
+ {
+ return Arrays.deepToString(memory);
+ }
+ }
+}
--- /dev/null
+package net.mograsim.machine.standard.memory;
+
+import java.util.Map;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.model.model.wires.Pin;
+import net.mograsim.logic.model.modeladapter.LogicModelParameters;
+import net.mograsim.logic.model.modeladapter.componentadapters.ComponentAdapter;
+
+public class WordAddressableMemoryAdapter implements ComponentAdapter<GUIMemoryWA>
+{
+
+ @Override
+ public Class<GUIMemoryWA> getSupportedClass()
+ {
+ return GUIMemoryWA.class;
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIMemoryWA guiComponent,
+ Map<Pin, Wire> logicWiresPerPin)
+ {
+ ReadWriteEnd data = logicWiresPerPin.get(guiComponent.getDataPin()).createReadWriteEnd();
+ ReadEnd address = logicWiresPerPin.get(guiComponent.getAddressPin()).createReadOnlyEnd();
+ ReadEnd mode = logicWiresPerPin.get(guiComponent.getReadWritePin()).createReadOnlyEnd();
+ new WordAddressableMemoryComponent(timeline, 2, guiComponent.maximalAddress, guiComponent.minimalAddress, data, mode, address);
+ }
+
+}
--- /dev/null
+package net.mograsim.machine.standard.memory;
+
+import java.util.List;
+
+import net.mograsim.logic.core.components.BasicComponent;
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+
+/**
+ * A memory component that only allows access to words of a specific length
+ */
+public class WordAddressableMemoryComponent extends BasicComponent
+{
+ private final WordAddressableMemory memory;
+ private final static Bit read = Bit.ONE;
+
+ private ReadWriteEnd data;
+ private ReadEnd rWBit, address;
+
+ /**
+ * @param data The bits of this ReadEnd are the value that is written to/read from memory; The bit width of this wire is the width of
+ * a memory word
+ * @param rWBit The value of the 0th bit dictates the mode: 0: Write, 1: Read
+ * @param address The bits of this ReadEnd address the memory cell to read/write
+ */
+ public WordAddressableMemoryComponent(Timeline timeline, int processTime, long minimalAddress, long maximalAddress, ReadWriteEnd data,
+ ReadEnd rWBit, ReadEnd address)
+ {
+ super(timeline, processTime);
+ this.data = data;
+ this.rWBit = rWBit;
+ this.address = address;
+ data.registerObserver(this);
+ rWBit.registerObserver(this);
+ address.registerObserver(this);
+
+ memory = new WordAddressableMemory(data.length(), minimalAddress, maximalAddress);
+ }
+
+ @Override
+ protected void compute()
+ {
+ if (!address.hasNumericValue())
+ {
+ if (read.equals(rWBit.getValue()))
+ data.feedSignals(BitVector.of(Bit.U, data.length()));
+ else
+ data.clearSignals();
+ return;
+ }
+ long addressed = address.getUnsignedValue();
+ if (read.equals(rWBit.getValue()))
+ data.feedSignals(memory.getCell(addressed));
+ else
+ {
+ data.clearSignals();
+ memory.setCell(addressed, data.getValues());
+ }
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(data, rWBit, address);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(data);
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.machine.standard.memory;\r
+\r
+import static org.junit.jupiter.api.Assertions.assertEquals;\r
+\r
+import java.math.BigInteger;\r
+import java.util.Random;\r
+\r
+import org.junit.jupiter.api.Test;\r
+\r
+import net.mograsim.logic.core.timeline.Timeline;\r
+import net.mograsim.logic.core.types.Bit;\r
+import net.mograsim.logic.core.types.BitVector;\r
+import net.mograsim.logic.core.wires.Wire;\r
+import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;\r
+\r
+class WordAddressableMemoryTest {\r
+ \r
+ private Timeline t = new Timeline(10);\r
+\r
+ @Test\r
+ public void wordAddressableMemoryLargeTest()\r
+ {\r
+ Wire rW = new Wire(t, 1, 2);\r
+ Wire data = new Wire(t, 16, 2);\r
+ Wire address = new Wire(t, 64, 2);\r
+ ReadWriteEnd rWI = rW.createReadWriteEnd();\r
+ ReadWriteEnd dataI = data.createReadWriteEnd();\r
+ ReadWriteEnd addressI = address.createReadWriteEnd();\r
+\r
+ WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, 4096L, Long.MAX_VALUE, data.createReadWriteEnd(),\r
+ rW.createReadOnlyEnd(), address.createReadOnlyEnd());\r
+\r
+ Random r = new Random();\r
+ for (long j = 1; j > 0; j *= 2)\r
+ {\r
+ for (int i = 0; i < 50; i++)\r
+ {\r
+ String sAddress = String.format("%64s", BigInteger.valueOf(4096 + i + j).toString(2)).replace(' ', '0');\r
+ sAddress = new StringBuilder(sAddress).reverse().toString();\r
+ BitVector bAddress = BitVector.parse(sAddress);\r
+ addressI.feedSignals(bAddress);\r
+ t.executeAll();\r
+ String random = BigInteger.valueOf(Math.abs(r.nextInt())).toString(5);\r
+ random = random.substring(Integer.max(0, random.length() - 16));\r
+ random = String.format("%16s", random).replace(' ', '0');\r
+ random = random.replace('2', 'X').replace('3', 'Z').replace('4', 'U');\r
+ BitVector vector = BitVector.parse(random);\r
+ dataI.feedSignals(vector);\r
+ rWI.feedSignals(Bit.ZERO);\r
+ t.executeAll();\r
+ rWI.feedSignals(Bit.ONE);\r
+ t.executeAll();\r
+ dataI.clearSignals();\r
+ t.executeAll();\r
+\r
+ assertEquals(dataI.getValues(), vector);\r
+ }\r
+ }\r
+ }\r
+\r
+}\r