From: Fabian Stemmler Date: Fri, 24 May 2019 22:12:15 +0000 (+0200) Subject: WireEnd functionality split into ReadEnd and ReadWriteEnd X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=b7ce41467a2cbd9f45554982730741810e99feaa;p=Mograsim.git WireEnd functionality split into ReadEnd and ReadWriteEnd --- diff --git a/era.mi/src/era/mi/logic/components/BasicComponent.java b/era.mi/src/era/mi/logic/components/BasicComponent.java index e6952838..f89a72c7 100644 --- a/era.mi/src/era/mi/logic/components/BasicComponent.java +++ b/era.mi/src/era/mi/logic/components/BasicComponent.java @@ -2,7 +2,7 @@ package era.mi.logic.components; import era.mi.logic.Simulation; import era.mi.logic.types.BitVector; -import era.mi.logic.wires.Wire; +import era.mi.logic.wires.Wire.ReadEnd; import era.mi.logic.wires.WireObserver; /** @@ -26,7 +26,7 @@ public abstract class BasicComponent implements WireObserver, Component } @Override - public void update(Wire initiator, BitVector oldValues) + public void update(ReadEnd initiator, BitVector oldValues) { Simulation.TIMELINE.addEvent(e -> compute(), processTime); } diff --git a/era.mi/src/era/mi/logic/components/BitDisplay.java b/era.mi/src/era/mi/logic/components/BitDisplay.java index 971eb7a7..f34c9239 100644 --- a/era.mi/src/era/mi/logic/components/BitDisplay.java +++ b/era.mi/src/era/mi/logic/components/BitDisplay.java @@ -4,14 +4,15 @@ import java.util.List; import era.mi.logic.types.Bit; import era.mi.logic.types.BitVector; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class BitDisplay extends BasicComponent { - private final WireEnd in; + private final ReadEnd in; private BitVector displayedValue; - public BitDisplay(WireEnd in) + public BitDisplay(ReadEnd in) { super(1); this.in = in; @@ -36,13 +37,13 @@ public class BitDisplay extends BasicComponent } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(in); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(); } diff --git a/era.mi/src/era/mi/logic/components/Clock.java b/era.mi/src/era/mi/logic/components/Clock.java index 07419b46..f7648554 100644 --- a/era.mi/src/era/mi/logic/components/Clock.java +++ b/era.mi/src/era/mi/logic/components/Clock.java @@ -7,12 +7,13 @@ import era.mi.logic.timeline.TimelineEvent; import era.mi.logic.timeline.TimelineEventHandler; import era.mi.logic.types.Bit; import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class Clock implements TimelineEventHandler, Component { private boolean toggle = false; - private WireEnd out; + private ReadWriteEnd out; private int delta; /** @@ -20,7 +21,7 @@ public class Clock implements TimelineEventHandler, Component * @param out {@link Wire} the clock's impulses are fed into * @param delta ticks between rising and falling edge */ - public Clock(WireEnd out, int delta) + public Clock(ReadWriteEnd out, int delta) { this.delta = delta; this.out = out; @@ -35,7 +36,7 @@ public class Clock implements TimelineEventHandler, Component toggle = !toggle; } - public WireEnd getOut() + public ReadWriteEnd getOut() { return out; } @@ -46,13 +47,13 @@ public class Clock implements TimelineEventHandler, Component } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } diff --git a/era.mi/src/era/mi/logic/components/Component.java b/era.mi/src/era/mi/logic/components/Component.java index 522a58d9..f104e5fc 100644 --- a/era.mi/src/era/mi/logic/components/Component.java +++ b/era.mi/src/era/mi/logic/components/Component.java @@ -2,7 +2,8 @@ package era.mi.logic.components; import java.util.List; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public interface Component { @@ -11,10 +12,10 @@ public interface Component * Returns immutable list of all inputs to the {@link Component} (including e.g. the select bits to a MUX). Intended for visualization * in the UI. */ - public List getAllInputs(); + public List getAllInputs(); /** * Returns immutable list of all outputs to the {@link Component}. Intended for visualization in the UI. */ - public List getAllOutputs(); + public List getAllOutputs(); } diff --git a/era.mi/src/era/mi/logic/components/Connector.java b/era.mi/src/era/mi/logic/components/Connector.java index 89fb96eb..19367a57 100644 --- a/era.mi/src/era/mi/logic/components/Connector.java +++ b/era.mi/src/era/mi/logic/components/Connector.java @@ -4,17 +4,17 @@ import java.util.List; import era.mi.logic.Simulation; import era.mi.logic.types.BitVector; -import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; import era.mi.logic.wires.WireObserver; public class Connector implements WireObserver, Component { private boolean connected; - private final WireEnd a; - private final WireEnd b; + private final ReadWriteEnd a; + private final ReadWriteEnd b; - public Connector(WireEnd a, WireEnd b) + public Connector(ReadWriteEnd a, ReadWriteEnd b) { if (a.length() != b.length()) throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length(), b.length())); @@ -27,8 +27,8 @@ public class Connector implements WireObserver, Component public void connect() { connected = true; - update(a.getWire()); - update(b.getWire()); + update(a); + update(b); } public void disconnect() @@ -47,28 +47,28 @@ public class Connector implements WireObserver, Component } @Override - public void update(Wire initiator, BitVector oldValues) + public void update(ReadEnd initiator, BitVector oldValues) { if (connected) Simulation.TIMELINE.addEvent(e -> update(initiator), 1); } - private void update(Wire initiator) + private void update(ReadEnd initiator) { - if (initiator == a.getWire()) + if (initiator == a) b.feedSignals(a.wireValuesExcludingMe()); else a.feedSignals(b.wireValuesExcludingMe()); } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(a, b); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(a, b); } diff --git a/era.mi/src/era/mi/logic/components/Demux.java b/era.mi/src/era/mi/logic/components/Demux.java index 147dd7fe..21825961 100644 --- a/era.mi/src/era/mi/logic/components/Demux.java +++ b/era.mi/src/era/mi/logic/components/Demux.java @@ -3,7 +3,8 @@ package era.mi.logic.components; import java.util.List; import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; /** * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the @@ -14,8 +15,8 @@ import era.mi.logic.wires.Wire.WireEnd; */ public class Demux extends BasicComponent { - private final WireEnd select, in; - private final WireEnd[] outputs; + private final ReadEnd select, in; + private final ReadWriteEnd[] outputs; private final int outputSize; private int selected = -1; @@ -26,7 +27,7 @@ public class Demux extends BasicComponent * @param select Indexes the output array to which the input is mapped. Must have enough bits to index all outputs. * @param outputs One of these outputs receives the input signal, depending on the select bits */ - public Demux(int processTime, WireEnd in, WireEnd select, WireEnd... outputs) + public Demux(int processTime, ReadEnd in, ReadEnd select, ReadWriteEnd... outputs) { super(processTime); outputSize = in.length(); @@ -67,13 +68,13 @@ public class Demux extends BasicComponent } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(in, select); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(outputs); } diff --git a/era.mi/src/era/mi/logic/components/ManualSwitch.java b/era.mi/src/era/mi/logic/components/ManualSwitch.java index 0ad4a76c..caaf49b4 100644 --- a/era.mi/src/era/mi/logic/components/ManualSwitch.java +++ b/era.mi/src/era/mi/logic/components/ManualSwitch.java @@ -3,7 +3,8 @@ package era.mi.logic.components; import java.util.List; import era.mi.logic.types.Bit; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; /** * This class models a simple on/off (ONE/ZERO) switch for user interaction. @@ -13,10 +14,10 @@ import era.mi.logic.wires.Wire.WireEnd; */ public class ManualSwitch implements Component { - private WireEnd output; + private ReadWriteEnd output; private boolean isOn; - public ManualSwitch(WireEnd output) + public ManualSwitch(ReadWriteEnd output) { if (output.length() != 1) throw new IllegalArgumentException("Switch output can be only a single wire"); @@ -57,13 +58,13 @@ public class ManualSwitch implements Component } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(output); } diff --git a/era.mi/src/era/mi/logic/components/Merger.java b/era.mi/src/era/mi/logic/components/Merger.java index 34ba217c..a9d14101 100644 --- a/era.mi/src/era/mi/logic/components/Merger.java +++ b/era.mi/src/era/mi/logic/components/Merger.java @@ -4,13 +4,14 @@ import java.util.List; import era.mi.logic.types.BitVector; import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; import era.mi.logic.wires.WireObserver; public class Merger implements WireObserver, Component { - private WireEnd out; - private WireEnd[] inputs; + private ReadWriteEnd out; + private ReadEnd[] inputs; private int[] beginningIndex; /** @@ -18,7 +19,7 @@ public class Merger implements WireObserver, Component * @param union The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length(). * @param inputs The inputs to be merged into the union */ - public Merger(WireEnd union, WireEnd... inputs) + public Merger(ReadWriteEnd union, ReadEnd... inputs) { this.inputs = inputs; this.out = union; @@ -37,45 +38,45 @@ public class Merger implements WireObserver, Component "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length()."); } - public WireEnd getInput(int index) + public ReadEnd getInput(int index) { return inputs[index]; } - public WireEnd getUnion() + public ReadEnd getUnion() { return out; } @Override - public void update(Wire initiator, BitVector oldValues) + public void update(ReadEnd initiator, BitVector oldValues) { int index = find(initiator); int beginning = beginningIndex[index]; out.feedSignals(beginning, inputs[index].getValues()); } - private int find(Wire w) + private int find(ReadEnd r) { for (int i = 0; i < inputs.length; i++) - if (inputs[i].getWire() == w) + if (inputs[i] == r) return i; return -1; } - public WireEnd[] getInputs() + public ReadEnd[] getInputs() { return inputs.clone(); } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(inputs); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } diff --git a/era.mi/src/era/mi/logic/components/Mux.java b/era.mi/src/era/mi/logic/components/Mux.java index aea71166..b7cb6744 100644 --- a/era.mi/src/era/mi/logic/components/Mux.java +++ b/era.mi/src/era/mi/logic/components/Mux.java @@ -6,7 +6,8 @@ import java.util.Collections; import java.util.List; import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; /** * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the @@ -17,9 +18,9 @@ import era.mi.logic.wires.Wire.WireEnd; */ public class Mux extends BasicComponent { - private WireEnd select; - private WireEnd out; - private WireEnd[] inputs; + private ReadEnd select; + private ReadWriteEnd out; + private ReadEnd[] inputs; private final int outputSize; /** @@ -29,7 +30,7 @@ public class Mux extends BasicComponent * @param select Indexes the input array which is to be mapped to the output. Must have enough bits to index all inputs. * @param inputs One of these inputs is mapped to the output, depending on the select bits */ - public Mux(int processTime, WireEnd out, WireEnd select, WireEnd... inputs) + public Mux(int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs) { super(processTime); outputSize = out.length(); @@ -53,12 +54,12 @@ public class Mux extends BasicComponent this.out = out; } - public WireEnd getOut() + public ReadEnd getOut() { return out; } - public WireEnd getSelect() + public ReadEnd getSelect() { return select; } @@ -73,20 +74,20 @@ public class Mux extends BasicComponent return; } - WireEnd active = inputs[selectValue]; + ReadEnd active = inputs[selectValue]; out.feedSignals(active.getValues()); } @Override - public List getAllInputs() + public List getAllInputs() { - ArrayList wires = new ArrayList(Arrays.asList(inputs)); + ArrayList wires = new ArrayList(Arrays.asList(inputs)); wires.add(select); return Collections.unmodifiableList(wires); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } diff --git a/era.mi/src/era/mi/logic/components/Splitter.java b/era.mi/src/era/mi/logic/components/Splitter.java index 4764c27a..32841ab9 100644 --- a/era.mi/src/era/mi/logic/components/Splitter.java +++ b/era.mi/src/era/mi/logic/components/Splitter.java @@ -1,22 +1,24 @@ package era.mi.logic.components; +import java.util.List; + import era.mi.logic.types.BitVector; -import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; import era.mi.logic.wires.WireObserver; -public class Splitter implements WireObserver +public class Splitter implements WireObserver, Component { - private WireEnd input; - private WireEnd[] outputs; + private ReadEnd input; + private ReadWriteEnd[] outputs; - public Splitter(WireEnd input, WireEnd... outputs) + public Splitter(ReadEnd input, ReadWriteEnd... outputs) { this.input = input; this.outputs = outputs; input.addObserver(this); int length = 0; - for (WireEnd out : outputs) + for (ReadEnd out : outputs) length += out.length(); if (input.length() != length) @@ -36,8 +38,20 @@ public class Splitter implements WireObserver } @Override - public void update(Wire initiator, BitVector oldValues) + public void update(ReadEnd initiator, BitVector oldValues) { compute(); } + + @Override + public List getAllInputs() + { + return List.of(input); + } + + @Override + public List getAllOutputs() + { + return List.of(outputs); + } } diff --git a/era.mi/src/era/mi/logic/components/TriStateBuffer.java b/era.mi/src/era/mi/logic/components/TriStateBuffer.java index c0dd76e8..ee420566 100644 --- a/era.mi/src/era/mi/logic/components/TriStateBuffer.java +++ b/era.mi/src/era/mi/logic/components/TriStateBuffer.java @@ -3,14 +3,15 @@ package era.mi.logic.components; import java.util.List; import era.mi.logic.types.Bit; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class TriStateBuffer extends BasicComponent { - WireEnd in, enable; - WireEnd out; + ReadEnd in, enable; + ReadWriteEnd out; - public TriStateBuffer(int processTime, WireEnd in, WireEnd out, WireEnd enable) + public TriStateBuffer(int processTime, ReadEnd in, ReadWriteEnd out, ReadEnd enable) { super(processTime); if (in.length() != out.length()) @@ -35,13 +36,13 @@ public class TriStateBuffer extends BasicComponent } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(in, enable); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } diff --git a/era.mi/src/era/mi/logic/components/gates/AndGate.java b/era.mi/src/era/mi/logic/components/gates/AndGate.java index 5da680e4..e045982f 100644 --- a/era.mi/src/era/mi/logic/components/gates/AndGate.java +++ b/era.mi/src/era/mi/logic/components/gates/AndGate.java @@ -1,11 +1,12 @@ package era.mi.logic.components.gates; import era.mi.logic.types.BitVector.BitVectorMutator; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class AndGate extends MultiInputGate { - public AndGate(int processTime, WireEnd out, WireEnd... in) + public AndGate(int processTime, ReadWriteEnd out, ReadEnd... in) { super(processTime, BitVectorMutator::and, out, in); } diff --git a/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java index 0b4a5d09..dd8a6d6f 100644 --- a/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java +++ b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java @@ -5,16 +5,17 @@ import java.util.List; import era.mi.logic.components.BasicComponent; import era.mi.logic.types.BitVector.BitVectorMutator; import era.mi.logic.types.MutationOperation; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public abstract class MultiInputGate extends BasicComponent { - protected WireEnd[] in; - protected WireEnd out; + protected ReadEnd[] in; + protected ReadWriteEnd out; protected final int length; protected MutationOperation op; - protected MultiInputGate(int processTime, MutationOperation op, WireEnd out, WireEnd... in) + protected MultiInputGate(int processTime, MutationOperation op, ReadWriteEnd out, ReadEnd... in) { super(processTime); this.op = op; @@ -22,7 +23,7 @@ public abstract class MultiInputGate extends BasicComponent this.in = in.clone(); if (in.length < 1) throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length)); - for (WireEnd w : in) + for (ReadEnd w : in) { if (w.length() != length) throw new IllegalArgumentException("All wires connected to the gate must be of uniform length."); @@ -32,13 +33,13 @@ public abstract class MultiInputGate extends BasicComponent } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(in); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } @@ -47,7 +48,7 @@ public abstract class MultiInputGate extends BasicComponent protected void compute() { BitVectorMutator mutator = BitVectorMutator.empty(); - for (WireEnd w : in) + for (ReadEnd w : in) op.apply(mutator, w.getValues()); out.feedSignals(mutator.get()); } diff --git a/era.mi/src/era/mi/logic/components/gates/NotGate.java b/era.mi/src/era/mi/logic/components/gates/NotGate.java index 1c0d8330..150785b2 100644 --- a/era.mi/src/era/mi/logic/components/gates/NotGate.java +++ b/era.mi/src/era/mi/logic/components/gates/NotGate.java @@ -3,14 +3,15 @@ package era.mi.logic.components.gates; import java.util.List; import era.mi.logic.components.BasicComponent; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class NotGate extends BasicComponent { - private WireEnd in; - private WireEnd out; + private ReadEnd in; + private ReadWriteEnd out; - public NotGate(int processTime, WireEnd in, WireEnd out) + public NotGate(int processTime, ReadEnd in, ReadWriteEnd out) { super(processTime); this.in = in; @@ -24,24 +25,24 @@ public class NotGate extends BasicComponent out.feedSignals(in.getValues().not()); } - public WireEnd getIn() + public ReadEnd getIn() { return in; } - public WireEnd getOut() + public ReadEnd getOut() { return out; } @Override - public List getAllInputs() + public List getAllInputs() { return List.of(in); } @Override - public List getAllOutputs() + public List getAllOutputs() { return List.of(out); } diff --git a/era.mi/src/era/mi/logic/components/gates/OrGate.java b/era.mi/src/era/mi/logic/components/gates/OrGate.java index 8c1775fd..7450d8fb 100644 --- a/era.mi/src/era/mi/logic/components/gates/OrGate.java +++ b/era.mi/src/era/mi/logic/components/gates/OrGate.java @@ -1,11 +1,12 @@ package era.mi.logic.components.gates; import era.mi.logic.types.BitVector.BitVectorMutator; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; public class OrGate extends MultiInputGate { - public OrGate(int processTime, WireEnd out, WireEnd... in) + public OrGate(int processTime, ReadWriteEnd out, ReadEnd... in) { super(processTime, BitVectorMutator::or, out, in); } diff --git a/era.mi/src/era/mi/logic/components/gates/XorGate.java b/era.mi/src/era/mi/logic/components/gates/XorGate.java index 73a25568..7c8d740c 100644 --- a/era.mi/src/era/mi/logic/components/gates/XorGate.java +++ b/era.mi/src/era/mi/logic/components/gates/XorGate.java @@ -1,7 +1,8 @@ package era.mi.logic.components.gates; import era.mi.logic.types.BitVector.BitVectorMutator; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; /** * Outputs 1 when the number of 1 inputs is odd. @@ -10,7 +11,7 @@ import era.mi.logic.wires.Wire.WireEnd; */ public class XorGate extends MultiInputGate { - public XorGate(int processTime, WireEnd out, WireEnd... in) + public XorGate(int processTime, ReadWriteEnd out, ReadEnd... in) { super(processTime, BitVectorMutator::xor, out, in); } diff --git a/era.mi/src/era/mi/logic/tests/ComponentTest.java b/era.mi/src/era/mi/logic/tests/ComponentTest.java index 8a9bc5a4..2da847e3 100644 --- a/era.mi/src/era/mi/logic/tests/ComponentTest.java +++ b/era.mi/src/era/mi/logic/tests/ComponentTest.java @@ -1,6 +1,8 @@ package era.mi.logic.tests; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; import java.util.function.LongConsumer; @@ -20,9 +22,9 @@ import era.mi.logic.components.gates.XorGate; import era.mi.logic.types.Bit; import era.mi.logic.types.BitVector; import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; +import era.mi.logic.wires.Wire.ReadWriteEnd; -@SuppressWarnings("unused") class ComponentTest { @@ -89,7 +91,7 @@ class ComponentTest new TriStateBuffer(1, a.createReadOnlyEnd(), b.createEnd(), en.createReadOnlyEnd()); new TriStateBuffer(1, b.createReadOnlyEnd(), a.createEnd(), notEn.createReadOnlyEnd()); - WireEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd(); + ReadWriteEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd(); enI.feedSignals(Bit.ONE); aI.feedSignals(Bit.ONE); bI.feedSignals(Bit.Z); @@ -119,7 +121,7 @@ class ComponentTest { Simulation.TIMELINE.reset(); Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), out = new Wire(4, 1); - WireEnd selectIn = select.createEnd(); + ReadWriteEnd selectIn = select.createEnd(); selectIn.feedSignals(Bit.ZERO, Bit.ZERO); a.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); @@ -146,7 +148,7 @@ class ComponentTest { Simulation.TIMELINE.reset(); Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), in = new Wire(4, 1); - WireEnd selectIn = select.createEnd(); + ReadWriteEnd selectIn = select.createEnd(); selectIn.feedSignals(Bit.ZERO, Bit.ZERO); in.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO); @@ -240,7 +242,7 @@ class ComponentTest new NotGate(1, t2.createReadOnlyEnd(), q.createEnd()); new NotGate(1, t1.createReadOnlyEnd(), nq.createEnd()); - WireEnd sIn = s.createEnd(), rIn = r.createEnd(); + ReadWriteEnd sIn = s.createEnd(), rIn = r.createEnd(); sIn.feedSignals(Bit.ONE); rIn.feedSignals(Bit.ZERO); @@ -283,7 +285,7 @@ class ComponentTest { Simulation.TIMELINE.reset(); Wire w = new Wire(2, 1); - WireEnd wI1 = w.createEnd(), wI2 = w.createEnd(); + ReadWriteEnd wI1 = w.createEnd(), wI2 = w.createEnd(); wI1.feedSignals(Bit.ONE, Bit.Z); wI2.feedSignals(Bit.Z, Bit.X); Simulation.TIMELINE.executeAll(); @@ -298,8 +300,14 @@ class ComponentTest assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z); wI2.feedSignals(Bit.ONE, Bit.Z); - w.addObserver((i, oldValues) -> fail("WireArray notified observer, although value did not change.")); + ReadEnd rE = w.createReadOnlyEnd(); + rE.addObserver((i, oldValues) -> fail("WireEnd notified observer, although value did not change.")); Simulation.TIMELINE.executeAll(); + rE.close(); + wI1.feedSignals(Bit.X, Bit.X); + Simulation.TIMELINE.executeAll(); + wI1.addObserver((i, oldValues) -> fail("WireEnd notified observer, although it was closed.")); + wI1.close(); assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z); } @@ -313,9 +321,9 @@ class ComponentTest Wire a = new Wire(1, 2); Wire b = new Wire(1, 2); Wire c = new Wire(1, 2); - WireEnd aI = a.createEnd(); - WireEnd bI = b.createEnd(); - WireEnd cI = c.createEnd(); + ReadWriteEnd aI = a.createEnd(); + ReadWriteEnd bI = b.createEnd(); + ReadWriteEnd cI = c.createEnd(); TestBitDisplay test = new TestBitDisplay(c.createReadOnlyEnd()); TestBitDisplay test2 = new TestBitDisplay(a.createReadOnlyEnd()); diff --git a/era.mi/src/era/mi/logic/tests/TestBitDisplay.java b/era.mi/src/era/mi/logic/tests/TestBitDisplay.java index cb0494e1..82c0854d 100644 --- a/era.mi/src/era/mi/logic/tests/TestBitDisplay.java +++ b/era.mi/src/era/mi/logic/tests/TestBitDisplay.java @@ -7,12 +7,12 @@ import java.util.function.LongConsumer; import era.mi.logic.Simulation; import era.mi.logic.components.BitDisplay; import era.mi.logic.types.Bit; -import era.mi.logic.wires.Wire.WireEnd; +import era.mi.logic.wires.Wire.ReadEnd; public final class TestBitDisplay extends BitDisplay { - public TestBitDisplay(WireEnd in) + public TestBitDisplay(ReadEnd in) { super(in); } 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; diff --git a/era.mi/src/era/mi/logic/wires/WireObserver.java b/era.mi/src/era/mi/logic/wires/WireObserver.java index 9258e0a0..4c4bce0b 100644 --- a/era.mi/src/era/mi/logic/wires/WireObserver.java +++ b/era.mi/src/era/mi/logic/wires/WireObserver.java @@ -1,8 +1,9 @@ package era.mi.logic.wires; import era.mi.logic.types.BitVector; +import era.mi.logic.wires.Wire.ReadEnd; public interface WireObserver { - public void update(Wire initiator, BitVector oldValues); + public void update(ReadEnd initiator, BitVector oldValues); }