34ba217cf7a551806c2a4e732e15db9518357542
[Mograsim.git] / era.mi / src / era / mi / logic / components / Merger.java
1 package era.mi.logic.components;
2
3 import java.util.List;
4
5 import era.mi.logic.types.BitVector;
6 import era.mi.logic.wires.Wire;
7 import era.mi.logic.wires.Wire.WireEnd;
8 import era.mi.logic.wires.WireObserver;
9
10 public class Merger implements WireObserver, Component
11 {
12         private WireEnd out;
13         private WireEnd[] inputs;
14         private int[] beginningIndex;
15
16         /**
17          * 
18          * @param union  The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length().
19          * @param inputs The inputs to be merged into the union
20          */
21         public Merger(WireEnd union, WireEnd... inputs)
22         {
23                 this.inputs = inputs;
24                 this.out = union;
25                 this.beginningIndex = new int[inputs.length];
26
27                 int length = 0;
28                 for (int i = 0; i < inputs.length; i++)
29                 {
30                         beginningIndex[i] = length;
31                         length += inputs[i].length();
32                         inputs[i].addObserver(this);
33                 }
34
35                 if (length != union.length())
36                         throw new IllegalArgumentException(
37                                         "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length().");
38         }
39
40         public WireEnd getInput(int index)
41         {
42                 return inputs[index];
43         }
44
45         public WireEnd getUnion()
46         {
47                 return out;
48         }
49
50         @Override
51         public void update(Wire initiator, BitVector oldValues)
52         {
53                 int index = find(initiator);
54                 int beginning = beginningIndex[index];
55                 out.feedSignals(beginning, inputs[index].getValues());
56         }
57
58         private int find(Wire w)
59         {
60                 for (int i = 0; i < inputs.length; i++)
61                         if (inputs[i].getWire() == w)
62                                 return i;
63                 return -1;
64         }
65
66         public WireEnd[] getInputs()
67         {
68                 return inputs.clone();
69         }
70
71         @Override
72         public List<WireEnd> getAllInputs()
73         {
74                 return List.of(inputs);
75         }
76
77         @Override
78         public List<WireEnd> getAllOutputs()
79         {
80                 return List.of(out);
81         }
82 }