Finished MPROM support. Fixes #10
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / standard / memory / AbstractModelBitVectorMemory.java
1 package net.mograsim.machine.standard.memory;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.function.Consumer;
6
7 import net.mograsim.logic.model.model.LogicModelModifiable;
8 import net.mograsim.logic.model.model.wires.Pin;
9 import net.mograsim.logic.model.model.wires.PinUsage;
10 import net.mograsim.logic.model.modeladapter.LogicCoreAdapter;
11 import net.mograsim.logic.model.serializing.IdentifyParams;
12 import net.mograsim.logic.model.snippets.HighLevelStateHandler;
13 import net.mograsim.machine.BitVectorMemory;
14 import net.mograsim.machine.BitVectorMemoryDefinition;
15 import net.mograsim.machine.ModelMemory;
16
17 public abstract class AbstractModelBitVectorMemory<M extends BitVectorMemory, D extends BitVectorMemoryDefinition> extends ModelMemory
18 {
19         private final Pin addrPin, dataPin, rWPin;
20         private final D definition;
21         private final boolean readonly;
22
23         private CoreBitVectorMemory<M> memory;
24
25         private final List<Consumer<Object>> memoryBindingListeners;
26
27         public AbstractModelBitVectorMemory(LogicModelModifiable model, int width, int height, int aPinX, int dPinX, int rwPinX,
28                         boolean readonly, String centerText, D definition, String name)
29         {
30                 super(model, width, height, name, centerText, false);
31                 this.definition = definition;
32                 this.readonly = readonly;
33
34                 addPin(addrPin = new Pin(model, this, "A", definition.getMemoryAddressBits(), PinUsage.INPUT, width, aPinX));
35                 addPin(dataPin = new Pin(model, this, "D", definition.getCellWidth(), PinUsage.TRISTATE, width, dPinX));
36                 if (readonly)
37                         rWPin = null;
38                 else
39                         addPin(rWPin = new Pin(model, this, "RW", 1, PinUsage.INPUT, width, rwPinX));
40
41                 memoryBindingListeners = new ArrayList<>();
42
43                 setHighLevelStateHandler(new HighLevelStateHandler()
44                 {
45                         @Override
46                         public Object get(String stateID)
47                         {
48                                 if (stateID.equals("memory_binding"))
49                                         return memory.getMemory();
50                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
51                         }
52
53                         @Override
54                         public void set(String stateID, Object newState)
55                         {
56                                 if (stateID.equals("memory_binding"))
57                                 {
58                                         @SuppressWarnings("unchecked")
59                                         M mem = (M) newState;
60                                         memory.setMemory(mem);
61                                         memoryBindingListeners.forEach(l -> l.accept(newState));
62                                 } else
63                                         throw new IllegalArgumentException("No high level state with ID " + stateID);
64                         }
65
66                         @Override
67                         public void addListener(String stateID, Consumer<Object> stateChanged)
68                         {
69                                 if (stateID.equals("memory_binding"))
70                                         memoryBindingListeners.add(stateChanged);
71                                 else
72                                         throw new IllegalArgumentException("No high level state with ID " + stateID);
73                         }
74
75                         @Override
76                         public void removeListener(String stateID, Consumer<Object> stateChanged)
77                         {
78                                 if (stateID.equals("memory_binding"))
79                                         memoryBindingListeners.remove(stateChanged);
80                                 else
81                                         throw new IllegalArgumentException("No high level state with ID " + stateID);
82                         }
83
84                         @Override
85                         public String getIDForSerializing(IdentifyParams idParams)
86                         {
87                                 return null;
88                         }
89
90                         @Override
91                         public Object getParamsForSerializing(IdentifyParams idParams)
92                         {
93                                 return null;
94                         }
95                 });
96
97                 init();
98         }
99
100         public D getDefinition()
101         {
102                 return definition;
103         }
104
105         public Pin getAddressPin()
106         {
107                 return addrPin;
108         }
109
110         public Pin getDataPin()
111         {
112                 return dataPin;
113         }
114
115         public Pin getReadWritePin()
116         {
117                 if (isReadonly())
118                         throw new IllegalArgumentException("This AbstractModelBitVectorMemory has no RW pin; it is readonly");
119                 return rWPin;
120         }
121
122         public boolean isReadonly()
123         {
124                 return readonly;
125         }
126
127         public void setCoreModelBinding(CoreBitVectorMemory<M> memory)
128         {
129                 this.memory = memory;
130         }
131
132         public CoreBitVectorMemory<M> getCoreMemory()
133         {
134                 return memory;
135         }
136
137         static
138         {
139                 LogicCoreAdapter.addComponentAdapter(new BitVectorMemoryAdapter());
140         }
141 }