Renamed ViewModel to LogicModel
[Mograsim.git] / net.mograsim.logic.model.am2900 / src / net / mograsim / logic / model / am2900 / components / am2904 / ModelAm2904ShiftInstrDecode.java
1 package net.mograsim.logic.model.am2900.components.am2904;
2
3 import static net.mograsim.logic.core.types.Bit.ONE;
4 import static net.mograsim.logic.core.types.Bit.U;
5 import static net.mograsim.logic.core.types.Bit.X;
6 import static net.mograsim.logic.core.types.Bit.Z;
7 import static net.mograsim.logic.core.types.Bit.ZERO;
8
9 import java.util.Map;
10
11 import net.mograsim.logic.core.types.Bit;
12 import net.mograsim.logic.core.types.BitVector;
13 import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
14 import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
15 import net.mograsim.logic.model.model.LogicModelModifiable;
16 import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedModelComponent;
17 import net.mograsim.logic.model.model.wires.Pin;
18 import net.mograsim.logic.model.model.wires.PinUsage;
19 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
20 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer.PinNamesParams.Position;
21
22 public class ModelAm2904ShiftInstrDecode extends SimpleRectangularHardcodedModelComponent
23 {
24         public ModelAm2904ShiftInstrDecode(LogicModelModifiable model, String name)
25         {
26                 super(model, "Am2904ShiftInstrDecode", name, "Shift \ninstruction\ndecode");
27                 setSize(60, 80);
28                 addPin(new Pin(this, "I", 5, PinUsage.INPUT, 0, 25), Position.RIGHT);
29                 addPin(new Pin(this, "_SE", 1, PinUsage.INPUT, 0, 55), Position.RIGHT);
30                 // SIO0 MUX:
31                 // 000: 0
32                 // 001: 1
33                 // 01x: SIOn
34                 // 10x: QIOn
35                 // 11x: MC
36                 addPin(new Pin(this, "SIO0_MUX", 3, PinUsage.OUTPUT, 60, 5), Position.LEFT);
37                 // SIOn MUX:
38                 // 000: 0
39                 // 001: 1
40                 // 010: SIO0
41                 // 011: QIO0
42                 // 100: MC
43                 // 101: MN
44                 // 110: IC
45                 // 111: IN xor IVOR
46                 addPin(new Pin(this, "SIOn_MUX", 3, PinUsage.OUTPUT, 60, 15), Position.LEFT);
47                 // QIO0 MUX:
48                 // 000: 0
49                 // 001: 1
50                 // 01x: SIOn
51                 // 10x: QIOn
52                 // 11x: MC
53                 addPin(new Pin(this, "QIO0_MUX", 3, PinUsage.OUTPUT, 60, 25), Position.LEFT);
54                 // QIOn MUX:
55                 // 000: 0
56                 // 001: 1
57                 // 01x: SIO0
58                 // 10x: QIO0
59                 // 11x: MN
60                 addPin(new Pin(this, "QIOn_MUX", 3, PinUsage.OUTPUT, 60, 35), Position.LEFT);
61                 addPin(new Pin(this, "OEn", 1, PinUsage.OUTPUT, 60, 45), Position.LEFT);
62                 addPin(new Pin(this, "OE0", 1, PinUsage.OUTPUT, 60, 55), Position.LEFT);
63                 // 00: SIO0
64                 // 01: QIO0
65                 // 1x: SIOn
66                 addPin(new Pin(this, "MC_MUX", 2, PinUsage.OUTPUT, 60, 65), Position.LEFT);
67                 addPin(new Pin(this, "MC_EN", 1, PinUsage.OUTPUT, 60, 75), Position.LEFT);
68         }
69
70         @Override
71         public Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds)
72         {
73                 Bit _SE = readEnds.get("_SE").getValue();
74                 BitVector I = readEnds.get("I").getValues();
75                 readWriteEnds.get("OEn").feedSignals(I.getMSBit(0).not().and(_SE.not()));
76                 readWriteEnds.get("OE0").feedSignals(I.getMSBit(0).and(_SE.not()));
77                 if (_SE == Z || _SE == X)
78                 {
79                         readWriteEnds.get("SIO0_MUX").feedSignals(X, X, X);
80                         readWriteEnds.get("SIOn_MUX").feedSignals(X, X, X);
81                         readWriteEnds.get("QIO0_MUX").feedSignals(X, X, X);
82                         readWriteEnds.get("QIOn_MUX").feedSignals(X, X, X);
83                         readWriteEnds.get("MC_MUX").feedSignals(X, X);
84                         readWriteEnds.get("MC_EN").feedSignals(X);
85                         return null;
86                 } else if (_SE == U)
87                 {
88
89                         readWriteEnds.get("SIO0_MUX").feedSignals(U, U, U);
90                         readWriteEnds.get("SIOn_MUX").feedSignals(U, U, U);
91                         readWriteEnds.get("QIO0_MUX").feedSignals(U, U, U);
92                         readWriteEnds.get("QIOn_MUX").feedSignals(U, U, U);
93                         readWriteEnds.get("MC_MUX").feedSignals(U, U);
94                         readWriteEnds.get("MC_EN").feedSignals(U);
95                         return null;
96                 } else if (_SE == ONE)
97                 {
98                         readWriteEnds.get("SIO0_MUX").feedSignals(X, X, X);
99                         readWriteEnds.get("SIOn_MUX").feedSignals(X, X, X);
100                         readWriteEnds.get("QIO0_MUX").feedSignals(X, X, X);
101                         readWriteEnds.get("QIOn_MUX").feedSignals(X, X, X);
102                         readWriteEnds.get("MC_MUX").feedSignals(X, X);
103                         readWriteEnds.get("MC_EN").feedSignals(ZERO);
104                         return null;
105                 }
106                 if (!I.isBinary())
107                 {
108                         Bit val = null;
109                         for (Bit b : I.getBits())
110                                 if (!b.isBinary())
111                                 {
112                                         val = b;
113                                         break;
114                                 }
115                         readWriteEnds.get("SIO0_MUX").feedSignals(val, val, val);
116                         readWriteEnds.get("SIOn_MUX").feedSignals(val, val, val);
117                         readWriteEnds.get("QIO0_MUX").feedSignals(val, val, val);
118                         readWriteEnds.get("QIOn_MUX").feedSignals(val, val, val);
119                         readWriteEnds.get("MC_MUX").feedSignals(val, val);
120                         readWriteEnds.get("MC_EN").feedSignals(val);
121                         return null;
122                 }
123                 int IAsInt = I.getUnsignedValue().intValue();
124                 if (IAsInt < 16)
125                 {
126                         readWriteEnds.get("SIO0_MUX").feedSignals(X, X, X);
127                         readWriteEnds.get("QIO0_MUX").feedSignals(X, X, X);
128                         switch (IAsInt)
129                         {
130                         case 0:
131                         case 2:
132                         case 6:
133                         case 7:
134                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ZERO, ZERO);
135                                 break;
136                         case 1:
137                         case 3:
138                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ZERO, ONE);
139                                 break;
140                         case 4:
141                         case 9:
142                         case 12:
143                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ZERO, ZERO);
144                                 break;
145                         case 5:
146                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ZERO, ONE);
147                                 break;
148                         case 8:
149                         case 10:
150                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ONE, ZERO);
151                                 break;
152                         case 11:
153                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ONE, ZERO);
154                                 break;
155                         case 13:
156                         case 15:
157                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ONE, ONE);
158                                 break;
159                         case 14:
160                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ONE, ONE);
161                                 break;
162                         default:
163                                 throw new IllegalStateException("can't happen");
164                         }
165                         switch (IAsInt)
166                         {
167                         case 0:
168                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ZERO, ZERO);
169                                 break;
170                         case 1:
171                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ZERO, ONE);
172                                 break;
173                         case 2:
174                                 readWriteEnds.get("QIOn_MUX").feedSignals(ONE, ONE, X);
175                                 break;
176                         case 3:
177                         case 4:
178                         case 5:
179                         case 6:
180                         case 7:
181                         case 11:
182                         case 12:
183                         case 13:
184                         case 14:
185                         case 15:
186                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ONE, X);
187                                 break;
188                         case 8:
189                         case 9:
190                         case 10:
191                                 readWriteEnds.get("QIOn_MUX").feedSignals(ONE, ZERO, X);
192                                 break;
193                         default:
194                                 throw new IllegalStateException("can't happen");
195                         }
196                 } else
197                 {
198                         readWriteEnds.get("SIOn_MUX").feedSignals(X, X, X);
199                         readWriteEnds.get("QIOn_MUX").feedSignals(X, X, X);
200                         switch (IAsInt)
201                         {
202                         case 16:
203                         case 18:
204                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ZERO, ZERO);
205                                 break;
206                         case 17:
207                         case 19:
208                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ZERO, ONE);
209                                 break;
210                         case 20:
211                         case 21:
212                         case 22:
213                         case 23:
214                         case 28:
215                         case 29:
216                         case 30:
217                         case 31:
218                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ZERO, X);
219                                 break;
220                         case 24:
221                         case 26:
222                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ONE, X);
223                                 break;
224                         case 25:
225                         case 27:
226                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ONE, X);
227                                 break;
228                         default:
229                                 throw new IllegalStateException("can't happen");
230                         }
231                         switch (IAsInt)
232                         {
233                         case 16:
234                         case 18:
235                         case 20:
236                         case 22:
237                         case 27:
238                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ZERO, ZERO);
239                                 break;
240                         case 17:
241                         case 19:
242                         case 21:
243                         case 23:
244                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ZERO, ONE);
245                                 break;
246                         case 24:
247                         case 25:
248                         case 26:
249                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ZERO, X);
250                                 break;
251                         case 28:
252                         case 30:
253                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ONE, X);
254                                 break;
255                         case 29:
256                         case 31:
257                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ONE, X);
258                                 break;
259                         default:
260                                 throw new IllegalStateException("can't happen");
261                         }
262                 }
263                 // MC
264                 switch (IAsInt)
265                 {
266                 case 0:
267                 case 1:
268                 case 3:
269                 case 4:
270                 case 5:
271                 case 6:
272                 case 10:
273                 case 11:
274                 case 14:
275                 case 15:
276                 case 18:
277                 case 19:
278                 case 22:
279                 case 23:
280                 case 26:
281                 case 27:
282                 case 30:
283                 case 31:
284                         readWriteEnds.get("MC_EN").feedSignals(ZERO);
285                         readWriteEnds.get("MC_MUX").feedSignals(X, X);
286                         break;
287                 case 2:
288                 case 8:
289                 case 9:
290                         readWriteEnds.get("MC_EN").feedSignals(ONE);
291                         readWriteEnds.get("MC_MUX").feedSignals(ZERO, ZERO);
292                         break;
293                 case 7:
294                 case 12:
295                 case 13:
296                         readWriteEnds.get("MC_EN").feedSignals(ONE);
297                         readWriteEnds.get("MC_MUX").feedSignals(ZERO, ONE);
298                         break;
299                 case 16:
300                 case 17:
301                 case 20:
302                 case 21:
303                 case 24:
304                 case 25:
305                 case 28:
306                 case 29:
307                         readWriteEnds.get("MC_EN").feedSignals(ONE);
308                         readWriteEnds.get("MC_MUX").feedSignals(ONE, X);
309                         break;
310                 default:
311                         throw new IllegalStateException("can't happen");
312                 }
313                 return null;
314         }
315
316         static
317         {
318                 IndirectModelComponentCreator.setComponentSupplier(ModelAm2904ShiftInstrDecode.class.getCanonicalName(),
319                                 (m, p, n) -> new ModelAm2904ShiftInstrDecode(m, n));
320         }
321 }