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