d98e0f15448da01ecfc0c06c8ab5e081bfca5fbc
[Mograsim.git] / era.mi / src / era / mi / logic / components / Mux.java
1 package era.mi.logic.components;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Arrays;\r
5 import java.util.Collections;\r
6 import java.util.List;\r
7 \r
8 import era.mi.logic.wires.WireArray;\r
9 import era.mi.logic.wires.WireArray.WireArrayInput;\r
10 \r
11 /**\r
12  * Models a multiplexer. Takes an arbitrary amount of input {@link WireArray}s, one of which, as determined by select, is put through to the\r
13  * output.\r
14  * \r
15  * @author Fabian Stemmler\r
16  *\r
17  */\r
18 public class Mux extends BasicComponent {\r
19         private WireArray select;\r
20         private WireArrayInput outI;\r
21         private WireArray[] inputs;\r
22         private final int outputSize;\r
23 \r
24         /**\r
25          * Input {@link WireArray}s and out must be of uniform length\r
26          * \r
27          * @param out    Must be of uniform length with all inputs.\r
28          * @param select Indexes the input array which is to be mapped to the output. Must have enough bits to index all inputs.\r
29          * @param inputs One of these inputs is mapped to the output, depending on the select bits\r
30          */\r
31         public Mux(int processTime, WireArray out, WireArray select, WireArray... inputs) {\r
32                 super(processTime);\r
33                 outputSize = out.length;\r
34 \r
35                 this.inputs = inputs.clone();\r
36                 for (int i = 0; i < this.inputs.length; i++) {\r
37                         if (inputs[i].length != outputSize)\r
38                                 throw new IllegalArgumentException("All MUX wire arrays must be of uniform length!");\r
39                         inputs[i].addObserver(this);\r
40                 }\r
41 \r
42                 this.select = select;\r
43                 select.addObserver(this);\r
44 \r
45                 int maxInputs = 1 << select.length;\r
46                 if (this.inputs.length > maxInputs)\r
47                         throw new IllegalArgumentException("There are more inputs (" + this.inputs.length + ") to the MUX than supported by "\r
48                                         + select.length + " select bits (" + maxInputs + ").");\r
49 \r
50                 outI = out.createInput();\r
51         }\r
52 \r
53         public WireArray getOut() {\r
54                 return outI.owner;\r
55         }\r
56 \r
57         public WireArray getSelect() {\r
58                 return select;\r
59         }\r
60 \r
61         @Override\r
62         public void compute() {\r
63                 int selectValue;\r
64                 if (!select.hasNumericValue() || (selectValue = (int) select.getUnsignedValue()) >= inputs.length) {\r
65                         outI.clearSignals();\r
66                         return;\r
67                 }\r
68 \r
69                 WireArray active = inputs[selectValue];\r
70                 outI.feedSignals(active.getValues());\r
71         }\r
72 \r
73         @Override\r
74         public List<WireArray> getAllInputs() {\r
75                 ArrayList<WireArray> wires = new ArrayList<WireArray>(Arrays.asList(inputs));\r
76                 wires.add(select);\r
77                 return Collections.unmodifiableList(wires);\r
78         }\r
79 \r
80         @Override\r
81         public List<WireArray> getAllOutputs() {\r
82                 return Collections.unmodifiableList(Arrays.asList(outI.owner));\r
83         }\r
84 }\r