From 1c7820abab8dc28939e35275f24a9c25e139add5 Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Tue, 20 Aug 2019 14:24:06 +0200 Subject: [PATCH] Moved WordAddressableMemoryComponent to new package --- .../gates/WordAddressableMemoryComponent.java | 198 ------------------ .../memory/WordAddressableMemory.java | 80 +++++++ .../WordAddressableMemoryComponent.java | 77 +++++++ .../logic/core/tests/ComponentTest.java | 2 +- 4 files changed, 158 insertions(+), 199 deletions(-) delete mode 100644 net.mograsim.logic.core/src/net/mograsim/logic/core/components/gates/WordAddressableMemoryComponent.java create mode 100644 net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemory.java create mode 100644 net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemoryComponent.java diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/gates/WordAddressableMemoryComponent.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/gates/WordAddressableMemoryComponent.java deleted file mode 100644 index d02a6078..00000000 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/gates/WordAddressableMemoryComponent.java +++ /dev/null @@ -1,198 +0,0 @@ -package net.mograsim.logic.core.components.gates; - -import java.util.Arrays; -import java.util.HashMap; -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; - -public class WordAddressableMemoryComponent extends BasicComponent -{ - private final WordAddressableMemory memory; - private final static Bit read = Bit.ONE; - - private ReadWriteEnd data; - private ReadEnd rWBit, address; - - /** - * - * @param timeline - * @param processTime - * @param minimalAddress - * @param maximalAddress - * @param data - * @param rWBit 0: Write 1: Read - * @param address - */ - 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(); - System.out.println(memory); - memory.setCell(addressed, data.getValues()); - } - } - - @Override - public List getAllInputs() - { - return List.of(data, rWBit, address); - } - - @Override - public List getAllOutputs() - { - return List.of(data); - } - - private class WordAddressableMemory - { - private final int cellWidth; - private final long minimalAddress, maximalAddress; - private final int pageSize; - - private HashMap pages; - - public WordAddressableMemory(int cellWidth, long minimalAddress, long maximalAddress) - { - super(); - this.cellWidth = cellWidth; - this.minimalAddress = minimalAddress; - this.maximalAddress = maximalAddress; - this.pages = new HashMap<>(); - this.pageSize = 64; - } - - public void setCell(long address, BitVector b) - { - if (address < minimalAddress || address > maximalAddress) - throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maimum: %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); - } - } - } -} -//import java.math.BigInteger; -// -//import net.mograsim.logic.core.types.Bit; -//import net.mograsim.logic.core.types.BitVector; -// -//private byte[] encode(BitVector v) -//{ -// BigInteger d = BigInteger.ZERO; -// Bit[] bits = v.getBits(); -// for (int i = v.length() - 1; i >= 0; i--) -// { -// d = d.add(BigInteger.valueOf(bits[i].ordinal())); -// d = d.multiply(BigInteger.valueOf(Bit.values().length)); -// } -// return d.toByteArray(); -//} -// -///** -// * -// * @param bytes -// * @param numBits length of the resulting BitVector -// * @return -// */ -//private BitVector decode(byte[] bytes, int numBits) -//{ -// BigInteger d = new BigInteger(bytes); -// Bit[] bits = new Bit[numBits]; -// return BitVector.of(bits); -//} -// -//private static class CellArray -//{ -// private byte[] bytes; -// private final static byte mask = -1; -// public CellArray(int numCells, int cellSize) -// { -// bytes = new byte[numCells * cellSize / 8]; -// } -// -// public byte[] getCell(int i) -// { -// -// } -//} diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemory.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemory.java new file mode 100644 index 00000000..fbb76c22 --- /dev/null +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemory.java @@ -0,0 +1,80 @@ +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 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 Maimum: %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); + } + } +} diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemoryComponent.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemoryComponent.java new file mode 100644 index 00000000..821b1f36 --- /dev/null +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/memory/WordAddressableMemoryComponent.java @@ -0,0 +1,77 @@ +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(); + System.out.println(memory); + memory.setCell(addressed, data.getValues()); + } + } + + @Override + public List getAllInputs() + { + return List.of(data, rWBit, address); + } + + @Override + public List getAllOutputs() + { + return List.of(data); + } + +} \ No newline at end of file diff --git a/net.mograsim.logic.core/test/net/mograsim/logic/core/tests/ComponentTest.java b/net.mograsim.logic.core/test/net/mograsim/logic/core/tests/ComponentTest.java index 5e4ae1c6..6055296f 100644 --- a/net.mograsim.logic.core/test/net/mograsim/logic/core/tests/ComponentTest.java +++ b/net.mograsim.logic.core/test/net/mograsim/logic/core/tests/ComponentTest.java @@ -22,8 +22,8 @@ import net.mograsim.logic.core.components.gates.NandGate; import net.mograsim.logic.core.components.gates.NorGate; import net.mograsim.logic.core.components.gates.NotGate; import net.mograsim.logic.core.components.gates.OrGate; -import net.mograsim.logic.core.components.gates.WordAddressableMemoryComponent; import net.mograsim.logic.core.components.gates.XorGate; +import net.mograsim.logic.core.components.memory.WordAddressableMemoryComponent; import net.mograsim.logic.core.timeline.Timeline; import net.mograsim.logic.core.types.Bit; import net.mograsim.logic.core.types.BitVector; -- 2.17.1