1 package net.mograsim.machine.standard.memory;
3 import java.math.BigInteger;
4 import java.util.Arrays;
5 import java.util.HashMap;
7 import net.mograsim.logic.core.types.Bit;
8 import net.mograsim.logic.core.types.BitVector;
9 import net.mograsim.machine.MainMemory;
10 import net.mograsim.machine.MainMemoryDefinition;
12 public class WordAddressableMemory implements MainMemory
14 private final int cellWidth;
15 private final long minimalAddress, maximalAddress;
16 private final MainMemoryDefinition definition;
17 private final int pageSize = 64;
19 private HashMap<Long, Page> pages;
21 public WordAddressableMemory(MainMemoryDefinition definition)
24 this.cellWidth = definition.getCellWidth();
25 this.minimalAddress = definition.getMinimalAddress();
26 this.maximalAddress = definition.getMaximalAddress();
27 this.definition = definition;
28 this.pages = new HashMap<>();
31 private void inBoundsCheck(long address)
33 if (address < minimalAddress || address > maximalAddress)
34 throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
35 minimalAddress, maximalAddress, address));
38 private long page(long address)
40 return address / pageSize;
43 private int offset(long address)
45 return (int) (address % pageSize);
49 public void setCell(long address, BitVector b)
51 inBoundsCheck(address);
52 long page = page(address);
53 int offset = offset(address);
54 Page p = pages.get(Long.valueOf(page));
56 pages.put(page, p = new Page());
61 public BitVector getCell(long address)
63 inBoundsCheck(address);
64 long page = page(address);
65 int offset = offset(address);
66 Page p = pages.get(Long.valueOf(page));
68 return BitVector.of(Bit.ZERO, cellWidth);
69 return p.getCell(offset);
73 public BigInteger getCellAsBigInteger(long address)
75 inBoundsCheck(address);
76 long page = page(address);
77 int offset = offset(address);
78 Page p = pages.get(Long.valueOf(page));
80 return BigInteger.valueOf(0L);
81 return p.getCellAsBigInteger(offset);
85 public void setCellAsBigInteger(long address, BigInteger word)
87 inBoundsCheck(address);
88 long page = page(address);
89 int offset = offset(address);
90 Page p = pages.get(Long.valueOf(page));
92 pages.put(page, p = new Page());
93 p.setCellAsBigInteger(offset, word);
98 private BitVector[] memory;
102 memory = new BitVector[pageSize];
105 public BitVector getCell(int index)
107 BitVector b = memory[index];
109 return BitVector.of(Bit.ZERO, cellWidth);
110 return memory[index];
113 public void setCell(int index, BitVector bits)
115 if (bits.width() != cellWidth)
116 throw new IllegalArgumentException(String.format(
117 "BitVector to be saved in memory cell has unexpected width. Expected: %d Actual: %d", cellWidth, bits.width()));
118 memory[index] = bits;
121 public void setCellAsBigInteger(int index, BigInteger bits)
123 setCell(index, BitVector.from(bits, cellWidth));
126 public BigInteger getCellAsBigInteger(int index)
129 return getCell(index).getUnsignedValue();
131 catch(NumberFormatException e)
133 throw new MemoryException(e);
138 public String toString()
140 return Arrays.deepToString(memory);
145 public MainMemoryDefinition getDefinition()