+ private void registerInput(WireArrayInput toRegister) {
+ inputs.add(toRegister);
+ }
+
+ /**
+ * A {@link WireArrayInput} feeds a constant signal into the {@link WireArray} it is tied to. The combination of all inputs determines
+ * the {@link WireArray}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 WireArrayInput {
+ public final WireArray owner;
+ private Bit[] inputValues;
+
+ private WireArrayInput(WireArray owner) {
+ super();
+ this.owner = owner;
+ initValues();
+ owner.registerInput(this);
+ }
+
+ private void initValues() {
+ inputValues = Bit.Z.makeArray(length);
+ }
+
+ /**
+ * Sets the wires values. This takes up time, as specified by the {@link WireArray}s travel time.
+ *
+ * @param newValues The new values the wires should take on.
+ *
+ * @author Fabian Stemmler
+ */
+ public void feedSignals(Bit... newValues) {
+ if (newValues.length == length) {
+ feedSignals(0, newValues);
+ } else
+ throw new IllegalArgumentException(
+ String.format("Attempted to input %o bits instead of %o bits.", newValues.length, length));
+ }
+
+ /**
+ * Sets values of a subarray of wires. This takes up time, as specified by the {@link WireArray}s travel time.
+ *
+ * @param newValues The new values the wires should take on.
+ * @param startingBit The first index of the subarray of wires.
+ *
+ * @author Fabian Stemmler
+ */
+ public void feedSignals(int startingBit, Bit... newValues) {
+ Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime);
+ }
+
+ private void setValues(int startingBit, Bit... newValues) {
+ int exclLastIndex = startingBit + newValues.length;
+ if (length < exclLastIndex)
+ throw new ArrayIndexOutOfBoundsException(
+ String.format("Attempted to input bits from index %o to %o when there are only %o wires.", startingBit,
+ exclLastIndex - 1, length));
+ if (!Arrays.equals(inputValues, startingBit, exclLastIndex, newValues, 0, newValues.length)) {
+ System.arraycopy(newValues, 0, inputValues, startingBit, newValues.length);
+ owner.recalculate();
+ }
+ }
+
+ /**
+ * Returns a copy (safe to modify) of the values the {@link WireArrayInput} is currently feeding into the associated
+ * {@link WireArray}.
+ */
+ public Bit[] getValues() {
+ return inputValues.clone();
+ }
+
+ /**
+ * {@link WireArrayInput} now feeds Z into the associated {@link WireArray}.
+ */
+ public void clearSignals() {
+ feedSignals(Bit.Z.makeArray(length));
+ }
+
+ public Bit[] wireValuesExcludingMe() {
+ Bit[] bits = Bit.Z.makeArray(length);
+ for (WireArrayInput wai : inputs) {
+ if (wai == this)
+ continue;
+ Util.combineInto(bits, wai.getValues());
+ }
+ return bits;
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.toString(inputValues);
+ }