Changed getCurrentMicroInstructionAddress to use HighLevelStates
[Mograsim.git] / plugins / net.mograsim.logic.model.am2900 / src / net / mograsim / logic / model / am2900 / machine / Am2900Machine.java
1 package net.mograsim.logic.model.am2900.machine;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import net.mograsim.logic.core.components.CoreClock;
7 import net.mograsim.logic.core.timeline.Timeline;
8 import net.mograsim.logic.core.types.BitVector;
9 import net.mograsim.logic.model.am2900.machine.registers.NumberedRegister;
10 import net.mograsim.logic.model.am2900.machine.registers.QRegister;
11 import net.mograsim.logic.model.model.LogicModel;
12 import net.mograsim.logic.model.model.LogicModelModifiable;
13 import net.mograsim.logic.model.model.components.ModelComponent;
14 import net.mograsim.logic.model.model.components.atomic.ModelClock;
15 import net.mograsim.logic.model.modeladapter.CoreModelParameters;
16 import net.mograsim.logic.model.modeladapter.LogicCoreAdapter;
17 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
18 import net.mograsim.machine.Machine;
19 import net.mograsim.machine.MachineDefinition;
20 import net.mograsim.machine.Register;
21 import net.mograsim.machine.mi.AssignableMicroInstructionMemory;
22 import net.mograsim.machine.mi.MicroInstruction;
23 import net.mograsim.machine.mi.MicroInstructionDefinition;
24 import net.mograsim.machine.mi.StandardMicroInstructionMemory;
25 import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
26 import net.mograsim.machine.mi.parameters.ParameterClassification;
27 import net.mograsim.machine.standard.memory.AssignableMainMemory;
28 import net.mograsim.machine.standard.memory.WordAddressableMemory;
29
30 public class Am2900Machine implements Machine
31 {
32         private Am2900MachineDefinition machineDefinition;
33         private LogicModelModifiable logicModel;
34         private ModelComponent am2900;
35         private Timeline timeline;
36         private AssignableMainMemory mainMemory;
37         private AssignableMicroInstructionMemory instMemory;
38         private CoreClock clock;
39         private long activeInstructionAddress;
40
41         private final Set<ActiveMicroInstructionChangedListener> amicListeners;
42
43         public Am2900Machine(LogicModelModifiable model, Am2900MachineDefinition am2900MachineDefinition)
44         {
45                 this.machineDefinition = am2900MachineDefinition;
46                 this.logicModel = model;
47                 this.am2900 = IndirectModelComponentCreator.createComponent(logicModel,
48                                 "resloader:Am2900Loader:jsonres:net/mograsim/logic/model/am2900/components/Am2900.json", "Am2900");
49                 this.amicListeners = new HashSet<>();
50
51                 CoreModelParameters params = new CoreModelParameters();
52                 params.gateProcessTime = 50;
53                 params.wireTravelTime = 10;
54                 mainMemory = new AssignableMainMemory(new WordAddressableMemory(am2900MachineDefinition.getMainMemoryDefinition()));
55                 instMemory = new AssignableMicroInstructionMemory(
56                                 new StandardMicroInstructionMemory(am2900MachineDefinition.getMicroInstructionMemoryDefinition()));
57                 timeline = LogicCoreAdapter.convert(logicModel, params);
58                 am2900.setHighLevelState("ram.memory_binding", mainMemory);
59                 am2900.setHighLevelState("mpm.memory_binding", instMemory);
60                 clock = logicModel.getComponentBySubmodelPath("Am2900.Clock#0", ModelClock.class).getClock();
61                 clock.registerObserver(c ->
62                 {
63                         if (clock.isOn())
64                         {
65                                 long oldAddress = activeInstructionAddress;
66                                 activeInstructionAddress = getCurrentMicroInstructionAddress();
67                                 notifyActiveMicroInstructionChangedListeners(oldAddress, activeInstructionAddress);
68                         }
69                 });
70         }
71
72         @Override
73         public MachineDefinition getDefinition()
74         {
75                 return machineDefinition;
76         }
77
78         @Override
79         public void reset()
80         {
81                 MicroInstructionDefinition muiDef = getDefinition().getMicroInstructionMemoryDefinition().getMicroInstructionDefinition();
82                 ParameterClassification[] paramClassifications = muiDef.getParameterClassifications();
83                 MicroInstructionParameter[] defaultParams = muiDef.createDefaultInstruction().getParameters();
84                 defaultParams[19] = paramClassifications[19].parse("JZ");
85                 MicroInstruction jzMI = MicroInstruction.create(defaultParams);
86                 am2900.setHighLevelState("muir_2.q", jzMI.toBitVector());
87         }
88
89         @Override
90         public LogicModel getModel()
91         {
92                 return logicModel;
93         }
94
95         public ModelComponent getAm2900()
96         {
97                 return am2900;
98         }
99
100         @Override
101         public Timeline getTimeline()
102         {
103                 return timeline;
104         }
105
106         @Override
107         public CoreClock getClock()
108         {
109                 return clock;
110         }
111
112         @Override
113         public BitVector getRegister(Register r)
114         {
115                 String am2901CellSuffix;
116                 if (r instanceof QRegister)
117                         am2901CellSuffix = "qreg.q";
118                 else if (r instanceof NumberedRegister)
119                         am2901CellSuffix = "regs.c" + ((NumberedRegister) r).getIndexAsBitstring() + ".q";
120                 else
121                         throw new IllegalArgumentException("Not a register of an Am2900Machine: " + r);
122                 BitVector result = BitVector.of();
123                 for (int i = 0; i < 16; i += 4)
124                 {
125                         String hlsID = String.format("am2901_%d-%d.%s", (i + 3), i, am2901CellSuffix);
126                         result = result.concat((BitVector) am2900.getHighLevelState(hlsID));
127                 }
128                 return result;
129         }
130
131         @Override
132         public void setRegister(Register r, BitVector value)
133         {
134                 String am2901CellSuffix;
135                 if (r instanceof QRegister)
136                         am2901CellSuffix = "qreg.q";
137                 else if (r instanceof NumberedRegister)
138                         am2901CellSuffix = "regs.c" + ((NumberedRegister) r).getIndexAsBitstring() + ".q";
139                 else
140                         throw new IllegalArgumentException("Not a register of an Am2900Machine: " + r);
141                 for (int i = 0; i < 16; i += 4)
142                 {
143                         String hlsID = String.format("am2901_%d-%d.%s", (i + 3), i, am2901CellSuffix);
144                         am2900.setHighLevelState(hlsID, value.subVector(i, i + 4));
145                 }
146         }
147
148         @Override
149         public AssignableMainMemory getMainMemory()
150         {
151                 return mainMemory;
152         }
153
154         @Override
155         public AssignableMicroInstructionMemory getMicroInstructionMemory()
156         {
157                 return instMemory;
158         }
159
160         @Override
161         public long getActiveMicroInstructionAddress()
162         {
163                 return activeInstructionAddress;
164         }
165
166         private long getCurrentMicroInstructionAddress()
167         {
168                 BitVector vector = (BitVector) am2900.getHighLevelState("mpm_address");
169                 return vector.isBinary() ? vector.getUnsignedValueLong() : -1;
170         }
171
172         @Override
173         public void addActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener)
174         {
175                 amicListeners.add(listener);
176         }
177
178         @Override
179         public void removeActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener)
180         {
181                 amicListeners.remove(listener);
182         }
183
184         private void notifyActiveMicroInstructionChangedListeners(long oldAddress, long newAddress)
185         {
186                 amicListeners.forEach(l -> l.instructionChanged(oldAddress, newAddress));
187         }
188 }