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