Added Clock input to CoreWordAddressableMemory
[Mograsim.git] / net.mograsim.machine / src / net / mograsim / machine / standard / memory / CoreWordAddressableMemory.java
1 package net.mograsim.machine.standard.memory;
2
3 import java.util.List;
4
5 import net.mograsim.logic.core.components.BasicCoreComponent;
6 import net.mograsim.logic.core.timeline.Timeline;
7 import net.mograsim.logic.core.types.Bit;
8 import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
9 import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
10 import net.mograsim.machine.MainMemoryDefinition;
11
12 /**
13  * A memory component that only allows access to words of a specific width
14  */
15 public class CoreWordAddressableMemory extends BasicCoreComponent
16 {
17         private final WordAddressableMemory memory;
18         private final static Bit read = Bit.ONE;
19
20         private ReadWriteEnd data;
21         private ReadEnd rWBit, address, clock;
22
23         /**
24          * @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
25          *                a memory word
26          * @param rWBit   The value of the 0th bit dictates the mode: 0: Write, 1: Read
27          * @param address The bits of this ReadEnd address the memory cell to read/write
28          */
29         public CoreWordAddressableMemory(Timeline timeline, int processTime, MainMemoryDefinition definition, ReadWriteEnd data,
30                         ReadEnd rWBit, ReadEnd address, ReadEnd clock)
31         {
32                 super(timeline, processTime);
33                 if(data.width() != definition.getCellWidth())
34                         throw new IllegalArgumentException(String.format("Bit width of data wire does not match main memory definition. Expected: %d Actual: %d", definition.getCellWidth(), data.width()));
35                 if(rWBit.width() != 1)
36                         throw new IllegalArgumentException(String.format("Bit width of read/write mode select wire is unexpected. Expected: 1 Actual: %d", rWBit.width()));
37                 if(address.width() != definition.getMemoryAddressBits())
38                         throw new IllegalArgumentException(String.format("Bit width of address wire does not match main memory definition. Expected: %d Actual: %d", definition.getMemoryAddressBits(), address.width()));
39                 this.data = data;
40                 this.rWBit = rWBit;
41                 this.address = address;
42                 this.clock = clock;
43                 data.registerObserver(this);
44                 rWBit.registerObserver(this);
45                 address.registerObserver(this);
46                 clock.registerObserver(this);
47                 
48                 memory = new WordAddressableMemory(definition);
49         }
50
51         @Override
52         protected void compute()
53         {
54                 if(clock.getValue() != Bit.ONE)
55                         return;
56                 if (!address.hasNumericValue())
57                 {
58                         if (read.equals(rWBit.getValue()))
59                                 data.feedSignals(Bit.U.toVector(data.width()));
60                         else
61                                 data.clearSignals();
62                         return;
63                 }
64                 long addressed = address.getUnsignedValue();
65                 if (read.equals(rWBit.getValue()))
66                         data.feedSignals(memory.getCell(addressed));
67                 else
68                 {
69                         data.clearSignals();
70                         memory.setCell(addressed, data.getValues());
71                 }
72         }
73
74         @Override
75         public List<ReadEnd> getAllInputs()
76         {
77                 return List.of(data, rWBit, address);
78         }
79
80         @Override
81         public List<ReadWriteEnd> getAllOutputs()
82         {
83                 return List.of(data);
84         }
85 }