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