X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.core%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fcore%2Fcomponents%2FUnidirectionalMerger.java;fp=net.mograsim.logic.core%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fcore%2Fcomponents%2FUnidirectionalMerger.java;h=f1c3f8bce0f95e39f5eefc21865defdcd1b29350;hb=4db274c53e53cda8321067eca57d524f188c2e6f;hp=0000000000000000000000000000000000000000;hpb=0ab3dafe756a69ff8b1e0137058caf2f5ac564aa;p=Mograsim.git diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/UnidirectionalMerger.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/UnidirectionalMerger.java new file mode 100644 index 00000000..f1c3f8bc --- /dev/null +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/UnidirectionalMerger.java @@ -0,0 +1,85 @@ +package net.mograsim.logic.core.components; + +import java.util.List; + +import net.mograsim.logic.core.LogicObservable; +import net.mograsim.logic.core.LogicObserver; +import net.mograsim.logic.core.timeline.Timeline; +import net.mograsim.logic.core.wires.Wire; +import net.mograsim.logic.core.wires.Wire.ReadEnd; +import net.mograsim.logic.core.wires.Wire.ReadWriteEnd; + +public class UnidirectionalMerger extends Component implements LogicObserver +{ + private ReadWriteEnd out; + private ReadEnd[] inputs; + private int[] beginningIndex; + + /** + * + * @param union The output of merging n {@link Wire}s into one. Must have width = a1.width() + a2.width() + ... + an.width(). + * @param inputs The inputs to be merged into the union + */ + public UnidirectionalMerger(Timeline timeline, ReadWriteEnd union, ReadEnd... inputs) + { + super(timeline); + this.inputs = inputs; + this.out = union; + this.beginningIndex = new int[inputs.length]; + + int width = 0; + for (int i = 0; i < inputs.length; i++) + { + beginningIndex[i] = width; + width += inputs[i].width(); + inputs[i].registerObserver(this); + } + + if (width != union.width()) + throw new IllegalArgumentException( + "The output of merging n WireArrays into one must have width = a1.width() + a2.width() + ... + an.width()."); + } + + public ReadEnd getInput(int index) + { + return inputs[index]; + } + + public ReadEnd getUnion() + { + return out; + } + + @Override + public void update(LogicObservable initiator) + { + int index = find(initiator); + int beginning = beginningIndex[index]; + out.feedSignals(beginning, inputs[index].getValues()); + } + + private int find(LogicObservable r) + { + for (int i = 0; i < inputs.length; i++) + if (inputs[i] == r) + return i; + return -1; + } + + public ReadEnd[] getInputs() + { + return inputs.clone(); + } + + @Override + public List getAllInputs() + { + return List.of(inputs); + } + + @Override + public List getAllOutputs() + { + return List.of(out); + } +}