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