Updated MainMemory interface
[Mograsim.git] / net.mograsim.machine / src / net / mograsim / machine / standard / memory / WordAddressableMemory.java
1 package net.mograsim.machine.standard.memory;
2
3 import java.util.Arrays;
4 import java.util.HashMap;
5
6 import net.mograsim.logic.core.types.Bit;
7 import net.mograsim.logic.core.types.BitVector;
8 import net.mograsim.machine.MainMemory;
9 import net.mograsim.machine.MainMemoryDefinition;
10
11 public class WordAddressableMemory implements MainMemory
12 {
13         private final int cellWidth;
14         private final long minimalAddress, maximalAddress;
15         private final MainMemoryDefinition definition;
16         private final int pageSize = 64;
17
18         private HashMap<Long, Page> pages;
19
20         public WordAddressableMemory(MainMemoryDefinition definition)
21         {
22                 super();
23                 this.cellWidth = definition.getCellWidth();
24                 this.minimalAddress = definition.getMinimalAddress();
25                 this.maximalAddress = definition.getMaximalAddress();
26                 this.definition = definition;
27                 this.pages = new HashMap<>();
28         }
29
30         @Override
31         public void setCell(long address, BitVector b)
32         {
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));
36                 long page = address / pageSize;
37                 int offset = (int) (address % pageSize);
38                 Page p = pages.get(Long.valueOf(page));
39                 if (p == null)
40                         pages.put(page, p = new Page());
41                 p.setCell(offset, b);
42         }
43
44         @Override
45         public BitVector getCell(long address)
46         {
47                 long page = address / pageSize;
48                 int offset = (int) (address % pageSize);
49                 Page p = pages.get(Long.valueOf(page));
50                 if (p == null)
51                         return BitVector.of(Bit.U, cellWidth);
52                 return p.getCell(offset);
53         }
54
55         private class Page
56         {
57                 private BitVector[] memory;
58
59                 public Page()
60                 {
61                         memory = new BitVector[pageSize];
62                 }
63
64                 public BitVector getCell(int index)
65                 {
66                         BitVector b = memory[index];
67                         if (b == null)
68                                 return BitVector.of(Bit.U, cellWidth);
69                         return memory[index];
70                 }
71
72                 public void setCell(int index, BitVector bits)
73                 {
74                         if (bits.length() != cellWidth)
75                                 throw new IllegalArgumentException(String.format(
76                                                 "BitVector to be saved in memory cell has unexpected length. Expected: %d Actual: %d", cellWidth, bits.length()));
77                         memory[index] = bits;
78                 }
79
80                 @Override
81                 public String toString()
82                 {
83                         return Arrays.deepToString(memory);
84                 }
85         }
86
87         @Override
88         public MainMemoryDefinition getDefinition()
89         {
90                 return definition;
91         }
92 }