X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.core%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fcore%2Fwires%2FWire.java;h=04ca9ce37450f84e94f83c00ffbd6dab13698c34;hb=e2cfc152b70fb4b2d8abb8ff4c901ceacf4c89cc;hp=bae4cb417ca4e970fb5d8f7eb1756471b4a83a25;hpb=6432c12630fa3f80ec19bf23229844abd42105e3;p=Mograsim.git diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java index bae4cb41..04ca9ce3 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java @@ -419,7 +419,11 @@ public class Wire timeline.addEvent(e -> setValues(startingBit, bitVector), travelTime); } - private void setValues(int startingBit, BitVector newValues) + /** + * Sets the values that are being fed into the {@link Wire}. The preferred way of setting {@link ReadWriteEnd} values is via + * feedValues(...) with a delay. + */ + void setValues(int startingBit, BitVector newValues) { // index check covered in equals if (!inputValues.equalsWithOffset(newValues, startingBit)) @@ -431,7 +435,11 @@ public class Wire } } - private void setValues(BitVector newValues) + /** + * Sets the values that are being fed into the {@link Wire}. The preferred way of setting {@link ReadWriteEnd} values is via + * feedValues(...) with a delay. + */ + void setValues(BitVector newValues) { if (inputValues.equals(newValues)) return; @@ -509,4 +517,58 @@ public class Wire inputs[i] = w[i].createReadWriteEnd(); return inputs; } + + /** + * @formatter:off + * Fuses the selected bits of two wires together. If the bits change in one Wire, the other is changed accordingly immediately. + * Warning: The bits are permanently fused together. + * @formatter:on + * @param a The {@link Wire} to be (partially) fused with b + * @param b The {@link Wire} to be (partially) fused with a + * @param fromA The first bit of {@link Wire} a to be fused + * @param fromB The first bit of {@link Wire} b to be fused + * @param length The amount of bits to fuse + */ + public static void fuse(Wire a, Wire b, int fromA, int fromB, int length) + { + ReadWriteEnd rA = a.createReadWriteEnd(), rB = b.createReadWriteEnd(); + rA.setValues(BitVector.of(Bit.Z, a.length)); + rB.setValues(BitVector.of(Bit.Z, b.length)); + rA.registerObserver(new Fusion(rB, fromA, fromB, length)); + rB.registerObserver(new Fusion(rA, fromB, fromA, length)); + } + + /** + * @formatter:off + * Fuses the selected bits of two wires together. If the bits change in one Wire, the other is changed accordingly immediately. + * Warning: The bits are permanently fused together. + * @formatter:on + * @param a The {@link Wire} to be fused with b + * @param b The {@link Wire} to be fused with a + */ + public static void fuse(Wire a, Wire b) + { + fuse(a, b, 0, 0, a.length); + } + + private static class Fusion implements LogicObserver + { + private ReadWriteEnd target; + int fromSource, fromTarget, length; + + public Fusion(ReadWriteEnd target, int fromSource, int fromTarget, int length) + { + this.target = target; + this.fromSource = fromSource; + this.fromTarget = fromTarget; + this.length = length; + } + + @Override + public void update(LogicObservable initiator) + { + ReadWriteEnd read = (ReadWriteEnd) initiator; + target.setValues(fromTarget, read.wireValuesExcludingMe().subVector(fromSource, fromSource + length)); + } + } } \ No newline at end of file