X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=era.mi%2Fsrc%2Fera%2Fmi%2Flogic%2Fwires%2FWire.java;h=9dba1fe56b842e548938d3887b8c3d69f8596400;hb=b7ce41467a2cbd9f45554982730741810e99feaa;hp=a7b96eeee1577fcceffbf66139c32cb041ae7572;hpb=cc5749d29d0a2e37262ec10925676c812a2fa734;p=Mograsim.git diff --git a/era.mi/src/era/mi/logic/wires/Wire.java b/era.mi/src/era/mi/logic/wires/Wire.java index a7b96eee..9dba1fe5 100644 --- a/era.mi/src/era/mi/logic/wires/Wire.java +++ b/era.mi/src/era/mi/logic/wires/Wire.java @@ -1,6 +1,7 @@ package era.mi.logic.wires; -import static era.mi.logic.types.Bit.*; +import static era.mi.logic.types.Bit.U; +import static era.mi.logic.types.Bit.Z; import java.util.ArrayList; import java.util.List; @@ -20,9 +21,9 @@ public class Wire { private BitVector values; public final int travelTime; - private List observers = new ArrayList(); + private List attached = new ArrayList(); public final int length; - private List inputs = new ArrayList(); + private List inputs = new ArrayList(); public Wire(int length, int travelTime) { @@ -47,7 +48,7 @@ public class Wire private void recalculateMultipleInputs() { BitVectorMutator mutator = BitVectorMutator.empty(); - for (WireEnd wireArrayEnd : inputs) + for (ReadWriteEnd wireArrayEnd : inputs) mutator.join(wireArrayEnd.getInputValues()); setNewValues(mutator.get()); } @@ -112,7 +113,6 @@ public class Wire case Z: case X: return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0; - // Random number? case ONE: val |= mask; break; @@ -170,57 +170,189 @@ public class Wire * * @author Fabian Stemmler */ - public boolean addObserver(WireObserver ob) + private void attachEnd(ReadEnd end) { - return observers.add(ob); + attached.add(end); + } + + private void detachEnd(ReadEnd end) + { + attached.remove(end); } private void notifyObservers(BitVector oldValues) { - for (WireObserver o : observers) - o.update(this, oldValues); + for (ReadEnd o : attached) + o.update(oldValues); } /** - * Create and register a {@link WireEnd} object, which is tied to this {@link Wire}. + * Create and register a {@link ReadWriteEnd} object, which is tied to this {@link Wire}. This {@link ReadWriteEnd} can be written to. */ - public WireEnd createEnd() + public ReadWriteEnd createEnd() { - return new WireEnd(false); + return new ReadWriteEnd(); } /** - * Create a {@link WireEnd} object, which is tied to this {@link Wire}. This {@link WireEnd} cannot written to. + * Create a {@link ReadEnd} object, which is tied to this {@link Wire}. This {@link ReadEnd} cannot be written to. */ - public WireEnd createReadOnlyEnd() + public ReadEnd createReadOnlyEnd() { - return new WireEnd(true); + return new ReadEnd(); } - private void registerInput(WireEnd toRegister) + private void registerInput(ReadWriteEnd toRegister) { inputs.add(toRegister); } /** - * A {@link WireEnd} feeds a constant signal into the {@link Wire} it is tied to. The combination of all inputs determines the + * A {@link ReadEnd} feeds a constant signal into the {@link Wire} it is tied to. The combination of all inputs determines the * {@link Wire}s final value. X dominates all other inputs Z does not affect the final value, unless there are no other inputs than Z 0 * and 1 turn into X when they are mixed * * @author Fabian Stemmler */ - public class WireEnd + public class ReadEnd + { + private List observers = new ArrayList(); + + private ReadEnd() + { + super(); + Wire.this.attachEnd(this); + } + + public void update(BitVector oldValues) + { + for (WireObserver ob : observers) + ob.update(this, oldValues); + } + + /** + * Included for convenient use on {@link Wire}s of length 1. + * + * @return The value of bit 0. + * + * @author Fabian Stemmler + */ + public Bit getValue() + { + return Wire.this.getValue(); + } + + /** + * @param index Index of the requested bit. + * @return The value of the indexed bit. + * + * @author Fabian Stemmler + */ + public Bit getValue(int index) + { + return Wire.this.getValue(index); + } + + /** + * @param index Index of the requested bit. + * @return The value of the indexed bit. + * + * @author Fabian Stemmler + */ + public BitVector getValues() + { + return Wire.this.getValues(); + } + + /** + * @param start Start of the wanted segment. (inclusive) + * @param end End of the wanted segment. (exclusive) + * @return The values of the segment of {@link Bit}s indexed. + * + * @author Fabian Stemmler + */ + public BitVector getValues(int start, int end) + { + return Wire.this.getValues(start, end); + } + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the + * same value), not Bit.X or Bit.Z. false is returned otherwise. + * + * @author Fabian Stemmler + */ + public boolean hasNumericValue() + { + return Wire.this.hasNumericValue(); + } + + /** + * The {@link Wire} is interpreted as an unsigned integer with n bits. + * + * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getUnsignedValue() + { + return Wire.this.getUnsignedValue(); + } + + /** + * The {@link Wire} is interpreted as a signed integer with n bits. + * + * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public long getSignedValue() + { + return Wire.this.getSignedValue(); + } + + @Override + public String toString() + { + return Wire.this.toString(); + } + + public void close() + { + inputs.remove(this); + detachEnd(this); + recalculate(); + } + + public int length() + { + return length; + } + + public boolean addObserver(WireObserver ob) + { + return observers.add(ob); + } + + public Wire getWire() + { + return Wire.this; + } + } + + public class ReadWriteEnd extends ReadEnd { private boolean open; private BitVector inputValues; - private WireEnd(boolean readOnly) + private ReadWriteEnd() { super(); - open = !readOnly; // TODO: that makes sense, doesn't it? + open = true; initValues(); - if (!readOnly) - registerInput(this); + registerInput(this); } private void initValues() @@ -286,7 +418,7 @@ public class Wire } /** - * @return The value (of bit 0) the {@link WireEnd} is currently feeding into the associated {@link Wire}. + * @return The value (of bit 0) the {@link ReadEnd} is currently feeding into the associated {@link Wire}. */ public Bit getInputValue() { @@ -294,7 +426,7 @@ public class Wire } /** - * @return The value which the {@link WireEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}. + * @return The value which the {@link ReadEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}. */ public Bit getInputValue(int index) { @@ -302,7 +434,7 @@ public class Wire } /** - * @return A copy (safe to modify) of the values the {@link WireEnd} is currently feeding into the associated {@link Wire}. + * @return A copy (safe to modify) of the values the {@link ReadEnd} is currently feeding into the associated {@link Wire}. */ public BitVector getInputValues() { @@ -315,7 +447,7 @@ public class Wire } /** - * {@link WireEnd} now feeds Z into the associated {@link Wire}. + * {@link ReadEnd} now feeds Z into the associated {@link Wire}. */ public void clearSignals() { @@ -325,7 +457,7 @@ public class Wire public BitVector wireValuesExcludingMe() { BitVectorMutator mutator = BitVectorMutator.empty(); - for (WireEnd wireEnd : inputs) + for (ReadWriteEnd wireEnd : inputs) { if (wireEnd == this) continue; @@ -334,115 +466,10 @@ public class Wire return mutator.get(); } - /** - * Included for convenient use on {@link Wire}s of length 1. - * - * @return The value of bit 0. - * - * @author Fabian Stemmler - */ - public Bit getValue() - { - return Wire.this.getValue(); - } - - /** - * @param index Index of the requested bit. - * @return The value of the indexed bit. - * - * @author Fabian Stemmler - */ - public Bit getValue(int index) - { - return Wire.this.getValue(index); - } - - /** - * @param index Index of the requested bit. - * @return The value of the indexed bit. - * - * @author Fabian Stemmler - */ - public BitVector getValues() - { - return Wire.this.getValues(); - } - - /** - * @param start Start of the wanted segment. (inclusive) - * @param end End of the wanted segment. (exclusive) - * @return The values of the segment of {@link Bit}s indexed. - * - * @author Fabian Stemmler - */ - public BitVector getValues(int start, int end) - { - return Wire.this.getValues(start, end); - } - - /** - * The {@link Wire} is interpreted as an unsigned integer with n bits. - * - * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the - * same value), not Bit.X or Bit.Z. false is returned otherwise. - * - * @author Fabian Stemmler - */ - public boolean hasNumericValue() - { - return Wire.this.hasNumericValue(); - } - - /** - * The {@link Wire} is interpreted as an unsigned integer with n bits. - * - * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. - * - * @author Fabian Stemmler - */ - public long getUnsignedValue() - { - return Wire.this.getUnsignedValue(); - } - - /** - * The {@link Wire} is interpreted as a signed integer with n bits. - * - * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. - * - * @author Fabian Stemmler - */ - public long getSignedValue() - { - return Wire.this.getSignedValue(); - } - @Override public String toString() { return inputValues.toString(); - // return String.format("%s \nFeeding: %s", WireArray.this.toString(), Arrays.toString(inputValues)); - } - - public void close() - { - inputs.remove(this); - open = false; - } - - public int length() - { - return length; - } - - public boolean addObserver(WireObserver ob) - { - return Wire.this.addObserver(ob); - } - - public Wire getWire() - { - return Wire.this; } } @@ -453,9 +480,9 @@ public class Wire // Arrays.toString(values), inputs.stream().map(i -> Arrays.toString(i.inputValues)).reduce((s1, s2) -> s1 + s2) } - public static WireEnd[] extractEnds(Wire[] w) + public static ReadEnd[] extractEnds(Wire[] w) { - WireEnd[] inputs = new WireEnd[w.length]; + ReadEnd[] inputs = new ReadEnd[w.length]; for (int i = 0; i < w.length; i++) inputs[i] = w[i].createEnd(); return inputs;