Cleaned up memory stuff
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / mi / components / CoreMicroInstructionMemory.java
1 package net.mograsim.machine.mi.components;
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.timeline.TimelineEventHandler;
8 import net.mograsim.logic.core.types.Bit;
9 import net.mograsim.logic.core.types.BitVector;
10 import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
11 import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
12 import net.mograsim.machine.MemoryObserver;
13 import net.mograsim.machine.mi.MicroInstructionMemory;
14 import net.mograsim.machine.mi.MicroInstructionMemoryDefinition;
15
16 public class CoreMicroInstructionMemory extends BasicCoreComponent
17 {
18         private final ReadWriteEnd data;
19         private final ReadEnd address;
20         private final MicroInstructionMemoryDefinition definition;
21         private final MemoryObserver memObs;
22         private MicroInstructionMemory memory;
23
24         public CoreMicroInstructionMemory(Timeline timeline, int processTime, MicroInstructionMemoryDefinition definition, ReadWriteEnd data,
25                         ReadEnd address)
26         {
27                 super(timeline, processTime);
28                 if (data.width() != definition.getMicroInstructionDefinition().sizeInBits())
29                         throw new IllegalArgumentException(
30                                         String.format("Bit width of data wire does not match microinstruction memory definition. Expected: %d Actual: %d",
31                                                         definition.getMicroInstructionDefinition().sizeInBits(), data.width()));
32                 if (address.width() != definition.getMemoryAddressBits())
33                         throw new IllegalArgumentException(
34                                         String.format("Bit width of address wire does not match microinstruction memory definition. Expected: %d Actual: %d",
35                                                         definition.getMemoryAddressBits(), address.width()));
36
37                 this.data = data;
38                 this.address = address;
39                 this.definition = definition;
40                 this.memObs = a -> update();
41                 address.registerObserver(this);
42         }
43
44         public void setMemory(MicroInstructionMemory memory)
45         {
46                 if (memory != null && !memory.getDefinition().equals(definition))
47                         throw new IllegalArgumentException("Memory of incorrect memory definition given");
48                 if (this.memory != null)
49                         this.memory.registerObserver(memObs);
50                 this.memory = memory;
51                 if (memory != null)
52                         memory.registerObserver(memObs);
53                 update();
54         }
55
56         public MicroInstructionMemory getMemory()
57         {
58                 return memory;
59         }
60
61         @Override
62         public List<ReadEnd> getAllInputs()
63         {
64                 return List.of(address);
65         }
66
67         @Override
68         public List<ReadWriteEnd> getAllOutputs()
69         {
70                 return List.of(data);
71         }
72
73         @Override
74         protected TimelineEventHandler compute()
75         {
76                 if (memory == null || !address.getValues().isBinary())
77                         return e -> data.feedSignals(Bit.U.toVector(data.width()));// TODO don't always feed U, but decide to feed X or U.
78                 long addressed = address.getValues().getUnsignedValueLong();
79                 BitVector storedData = memory.getCell(addressed).toBitVector();
80                 return e -> data.feedSignals(storedData);
81         }
82 }