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