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