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