bin deleted and ignored.
[Mograsim.git] / era.mi / src / era / mi / logic / components / Mux2.java
1 package era.mi.logic.components;
2
3 import era.mi.logic.Simulation;
4 import era.mi.logic.wires.WireArray;
5 import era.mi.logic.wires.WireArray.WireArrayInput;
6 import era.mi.logic.wires.WireArrayObserver;
7
8 /**
9  * Models a Multiplexer. A is selected when select bit is 1, B when select bit is 0. Outputs X otherwise.
10  * @author Fabian Stemmler
11  *
12  */
13 public class Mux2 implements WireArrayObserver
14 {
15         private WireArray select;
16         private WireArrayInput outI;
17         private WireArrayInput[] inputs;
18         private final int size;
19         private final int processTime;
20         private int selected;
21         
22         /**
23          * {@link WireArray}s a, b and out must be of uniform length, select
24          * @param out Must be of uniform length with a and b.
25          * @param select Indexes the input array which is to be mapped to the output
26          * @param inputs One of these inputs is mapped to the output, depending on the select wires 
27          */
28         public Mux2(int processTime, WireArray out, WireArray select, WireArray... inputs)
29         {
30                 this.processTime = processTime;
31                 size = out.length;
32                 
33                 this.inputs = new WireArrayInput[inputs.length];
34                 for(int i = 0; i < this.inputs.length; i++)
35                 {
36                         if(inputs[i].length != size)
37                                 throw new IllegalArgumentException("All MUX wire arrays must be of uniform length!");
38                         this.inputs[i] = inputs[i].createInput();
39                         inputs[i].addObserver(this);
40                 }
41                 
42                 this.select = select;
43                 select.addObserver(this);
44                 selected = -1;
45                 
46                 int maxInputs = 1 << select.length;
47                 if(this.inputs.length > maxInputs)
48                         throw new IllegalArgumentException("There are more inputs ("
49                                         + this.inputs.length + ") to the MUX than supported by "
50                                         + select.length + " select bits (" + maxInputs + ").");
51                 
52                 outI = out.createInput();
53                 out.addObserver(this);
54         }
55         
56         public WireArray getOut()
57         {
58                 return outI.owner;
59         }
60
61         public WireArray getSelect()
62         {
63                 return select;
64         }
65
66         @Override
67         public void update(WireArray initiator) {
68                 int selectValue;
69                 if(!select.hasNumericValue() || (selectValue = (int) select.getUnsignedValue()) > size)
70                 {
71                         if(initiator == select)
72                         {
73                                 Simulation.TIMELINE.addEvent((e) -> {
74                                         if(selected != -1)
75                                         {
76                                                 inputs[selected].clearSignals();
77                                                 selected = -1;
78                                                 outI.clearSignals();
79                                         }
80                                 }, processTime);
81                         }
82                         return;
83                 }
84                 
85                 WireArrayInput active = inputs[selectValue];
86                 Simulation.TIMELINE.addEvent((e) -> {
87                         if(initiator == select)
88                         {
89                                 if(selected != -1)
90                                         inputs[selected].clearSignals();
91                                 selected = selectValue;
92                                 active.feedSignals(outI.owner.getValues());
93                                 outI.feedSignals(active.owner.getValues());
94                         }
95                         else if(initiator == outI.owner)
96                                 active.feedSignals(outI.owner.getValues());
97                         else if(initiator == active.owner)
98                                 outI.feedSignals(active.owner.getValues());
99                 }, processTime);
100         }
101 }