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