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