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