+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import net.mograsim.logic.core.LogicObservable;
-import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.timeline.Timeline;
-
-/**
- * A basic component that recomputes all outputs (with a delay), when it is updated.
- *
- * @author Fabian Stemmler
- */
-public abstract class BasicComponent extends Component implements LogicObserver
-{
- private int processTime;
-
- /**
- *
- * @param processTime Amount of time this component takes to update its outputs. Must be more than 0, otherwise 1 is assumed.
- *
- * @author Fabian Stemmler
- */
- public BasicComponent(Timeline timeline, int processTime)
- {
- super(timeline);
- this.processTime = processTime > 0 ? processTime : 1;
- }
-
- @Override
- public void update(LogicObservable initiator)
- {
- timeline.addEvent(e -> compute(), processTime);
- }
-
- protected abstract void compute();
-}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import net.mograsim.logic.core.LogicObservable;
+import net.mograsim.logic.core.LogicObserver;
+import net.mograsim.logic.core.timeline.Timeline;
+
+/**
+ * A basic component that recomputes all outputs (with a delay), when it is updated.
+ *
+ * @author Fabian Stemmler
+ */
+public abstract class BasicCoreComponent extends CoreComponent implements LogicObserver
+{
+ private int processTime;
+
+ /**
+ *
+ * @param processTime Amount of time this component takes to update its outputs. Must be more than 0, otherwise 1 is assumed.
+ *
+ * @author Fabian Stemmler
+ */
+ public BasicCoreComponent(Timeline timeline, int processTime)
+ {
+ super(timeline);
+ this.processTime = processTime > 0 ? processTime : 1;
+ }
+
+ @Override
+ public void update(LogicObservable initiator)
+ {
+ timeline.addEvent(e -> compute(), processTime);
+ }
+
+ protected abstract void compute();
+}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.ArrayList;
-import java.util.Collection;
-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.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class BitDisplay extends BasicComponent implements LogicObservable
-{
- private Collection<LogicObserver> observers;
- private final ReadEnd in;
- private BitVector displayedValue;
-
- public BitDisplay(Timeline timeline, ReadEnd in)
- {
- super(timeline, 1);
- observers = new ArrayList<>();
- this.in = in;
- in.registerObserver(this);
- compute();
- }
-
- @Override
- protected void compute()
- {
- displayedValue = in.getValues();
- notifyObservers();
- }
-
- public BitVector getDisplayedValue()
- {
- return displayedValue;
- }
-
- public boolean isDisplaying(Bit... values)
- {
- return displayedValue.equals(BitVector.of(values));
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(in);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of();
- }
-
- @Override
- public void registerObserver(LogicObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(LogicObserver ob)
- {
- observers.remove(ob);
- }
-
- @Override
- public void notifyObservers()
- {
- observers.forEach(ob -> ob.update(this));
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.Collection;
-import java.util.HashSet;
-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.timeline.TimelineEvent;
-import net.mograsim.logic.core.timeline.TimelineEventHandler;
-import net.mograsim.logic.core.types.Bit;
-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 Clock extends Component implements TimelineEventHandler, LogicObservable
-{
- private Collection<LogicObserver> observers;
- private boolean toggle = false;
- private ReadWriteEnd out;
- private int delta;
-
- /**
- *
- * @param out {@link Wire} the clock's impulses are fed into
- * @param delta ticks between rising and falling edge
- */
- public Clock(Timeline timeline, ReadWriteEnd out, int delta)
- {
- super(timeline);
- this.delta = delta;
- this.out = out;
- this.observers = new HashSet<>();
- addToTimeline();
- }
-
- @Override
- public void handle(TimelineEvent e)
- {
- addToTimeline();
- out.feedSignals(toggle ? Bit.ONE : Bit.ZERO);
- toggle = !toggle;
- notifyObservers();
- }
-
- public ReadWriteEnd getOut()
- {
- return out;
- }
-
- public boolean isOn()
- {
- return !toggle;
- }
-
- private void addToTimeline()
- {
- timeline.addEvent(this, delta);
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of();
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-
- @Override
- public void registerObserver(LogicObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(LogicObserver ob)
- {
- observers.remove(ob);
- }
-
- @Override
- public void notifyObservers()
- {
- observers.forEach(ob -> ob.update(this));
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.List;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public abstract class Component
-{
- protected Timeline timeline;
-
- public Component(Timeline timeline)
- {
- this.timeline = timeline;
- }
-
- /**
- * 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 abstract List<ReadEnd> getAllInputs();
-
- /**
- * Returns immutable list of all outputs to the {@link Component}. Intended for visualization in the UI.
- */
- public abstract List<ReadWriteEnd> getAllOutputs();
-}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreBitDisplay extends BasicCoreComponent implements LogicObservable
+{
+ private Collection<LogicObserver> observers;
+ private final ReadEnd in;
+ private BitVector displayedValue;
+
+ public CoreBitDisplay(Timeline timeline, ReadEnd in)
+ {
+ super(timeline, 1);
+ observers = new ArrayList<>();
+ this.in = in;
+ in.registerObserver(this);
+ compute();
+ }
+
+ @Override
+ protected void compute()
+ {
+ displayedValue = in.getValues();
+ notifyObservers();
+ }
+
+ public BitVector getDisplayedValue()
+ {
+ return displayedValue;
+ }
+
+ public boolean isDisplaying(Bit... values)
+ {
+ return displayedValue.equals(BitVector.of(values));
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(in);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of();
+ }
+
+ @Override
+ public void registerObserver(LogicObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(LogicObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ @Override
+ public void notifyObservers()
+ {
+ observers.forEach(ob -> ob.update(this));
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.Collection;
+import java.util.HashSet;
+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.timeline.TimelineEvent;
+import net.mograsim.logic.core.timeline.TimelineEventHandler;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreClock extends CoreComponent implements TimelineEventHandler, LogicObservable
+{
+ private Collection<LogicObserver> observers;
+ private boolean toggle = false;
+ private ReadWriteEnd out;
+ private int delta;
+
+ /**
+ *
+ * @param out {@link CoreWire} the clock's impulses are fed into
+ * @param delta ticks between rising and falling edge
+ */
+ public CoreClock(Timeline timeline, ReadWriteEnd out, int delta)
+ {
+ super(timeline);
+ this.delta = delta;
+ this.out = out;
+ this.observers = new HashSet<>();
+ addToTimeline();
+ }
+
+ @Override
+ public void handle(TimelineEvent e)
+ {
+ addToTimeline();
+ out.feedSignals(toggle ? Bit.ONE : Bit.ZERO);
+ toggle = !toggle;
+ notifyObservers();
+ }
+
+ public ReadWriteEnd getOut()
+ {
+ return out;
+ }
+
+ public boolean isOn()
+ {
+ return !toggle;
+ }
+
+ private void addToTimeline()
+ {
+ timeline.addEvent(this, delta);
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of();
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+
+ @Override
+ public void registerObserver(LogicObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(LogicObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ @Override
+ public void notifyObservers()
+ {
+ observers.forEach(ob -> ob.update(this));
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.List;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public abstract class CoreComponent
+{
+ protected Timeline timeline;
+
+ public CoreComponent(Timeline timeline)
+ {
+ this.timeline = timeline;
+ }
+
+ /**
+ * Returns immutable list of all inputs to the {@link CoreComponent} (including e.g. the select bits to a MUX). Intended for visualization
+ * in the UI.
+ */
+ public abstract List<ReadEnd> getAllInputs();
+
+ /**
+ * Returns immutable list of all outputs to the {@link CoreComponent}. Intended for visualization in the UI.
+ */
+ public abstract List<ReadWriteEnd> getAllOutputs();
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.List;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+/**
+ * Models a multiplexer. Takes an arbitrary amount of input {@link CoreWire}s, one of which, as determined by select, is put through to the
+ * output.
+ *
+ * @author Fabian Stemmler
+ *
+ */
+public class CoreDemux extends BasicCoreComponent
+{
+ private final ReadEnd select, in;
+ private final ReadWriteEnd[] outputs;
+ private final int outputSize;
+ private int selected = -1;
+
+ /**
+ * Output {@link CoreWire}s and in must be of uniform width
+ *
+ * @param in Must be of uniform width with all outputs.
+ * @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 CoreDemux(Timeline timeline, int processTime, ReadEnd in, ReadEnd select, ReadWriteEnd... outputs)
+ {
+ super(timeline, processTime);
+ outputSize = in.width();
+
+ this.in = in;
+ this.outputs = outputs;
+ for (int i = 0; i < this.outputs.length; i++)
+ {
+ if (outputs[i].width() != outputSize)
+ throw new IllegalArgumentException("All DEMUX wire arrays must be of uniform width!");
+ this.outputs[i] = outputs[i];
+ }
+
+ this.select = select;
+ select.registerObserver(this);
+
+ int maxInputs = 1 << select.width();
+ if (this.outputs.length > maxInputs)
+ throw new IllegalArgumentException("There are more outputs (" + this.outputs.length + ") to the DEMUX than supported by "
+ + select.width() + " select bits (" + maxInputs + ").");
+ in.registerObserver(this);
+ }
+
+ @Override
+ public void compute()
+ {
+ int selectValue = select.hasNumericValue() ? (int) select.getUnsignedValue() : -1;
+ if (selectValue >= outputs.length)
+ selectValue = -1;
+
+ if (selected != selectValue && selected != -1)
+ outputs[selected].clearSignals();
+
+ selected = selectValue;
+
+ if (selectValue != -1)
+ outputs[selectValue].feedSignals(in.getValues());
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(in, select);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(outputs);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+/**
+ * This class models a simple on/off (ONE/ZERO) switch for user interaction.
+ *
+ * @author Christian Femers
+ *
+ */
+public class CoreManualSwitch extends CoreComponent implements LogicObservable
+{
+ private Collection<LogicObserver> observers;
+ private ReadWriteEnd output;
+ private BitVector inputValues;
+
+ public CoreManualSwitch(Timeline timeline, ReadWriteEnd output)
+ {
+ super(timeline);
+ observers = new ArrayList<>();
+ this.output = output;
+ this.inputValues = output.getInputValues();
+ }
+
+ public void switchFullOn()
+ {
+ setState(BitVector.of(Bit.ONE, output.width()));
+ }
+
+ public void switchFullOff()
+ {
+ setState(BitVector.of(Bit.ZERO, output.width()));
+ }
+
+ public void toggle()
+ {
+ if (isFullOn())
+ switchFullOff();
+ else
+ switchFullOn();
+ }
+
+ public void setState(Bit bit)
+ {
+ setState(BitVector.of(bit));
+ }
+
+ public void setState(BitVector bits)
+ {
+ if (bits.length() != output.width())
+ throw new IllegalArgumentException("Incorrect bit vector length");
+ if (bits.equals(inputValues))
+ return;
+ inputValues = bits;
+ output.feedSignals(bits);
+ notifyObservers();
+ }
+
+ public boolean isFullOn()
+ {
+ return BitVector.of(Bit.ONE, output.width()).equals(output.getInputValues());
+ }
+
+ public BitVector getValues()
+ {
+ return inputValues;
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of();
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(output);
+ }
+
+ @Override
+ public void registerObserver(LogicObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(LogicObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ @Override
+ public void notifyObservers()
+ {
+ observers.forEach(ob -> ob.update(this));
+ }
+
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+/**
+ * Models a multiplexer. Takes an arbitrary amount of input {@link CoreWire}s, one of which, as determined by select, is put through to the
+ * output.
+ *
+ * @author Fabian Stemmler
+ *
+ */
+public class CoreMux extends BasicCoreComponent
+{
+ private ReadEnd select;
+ private ReadWriteEnd out;
+ private ReadEnd[] inputs;
+ private final int outputSize;
+
+ /**
+ * Input {@link CoreWire}s and out must be of uniform width
+ *
+ * @param out Must be of uniform width with all inputs.
+ * @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 CoreMux(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs)
+ {
+ super(timeline, processTime);
+ outputSize = out.width();
+
+ this.inputs = inputs.clone();
+ for (int i = 0; i < this.inputs.length; i++)
+ {
+ if (inputs[i].width() != outputSize)
+ throw new IllegalArgumentException("All MUX wire arrays must be of uniform width!");
+ inputs[i].registerObserver(this);
+ }
+
+ this.select = select;
+ select.registerObserver(this);
+
+ int maxInputs = 1 << select.width();
+ if (this.inputs.length > maxInputs)
+ throw new IllegalArgumentException("There are more inputs (" + this.inputs.length + ") to the MUX than supported by "
+ + select.width() + " select bits (" + maxInputs + ").");
+
+ this.out = out;
+ }
+
+ public ReadEnd getOut()
+ {
+ return out;
+ }
+
+ public ReadEnd getSelect()
+ {
+ return select;
+ }
+
+ @Override
+ public void compute()
+ {
+ int selectValue;
+ if (!select.hasNumericValue() || (selectValue = (int) select.getUnsignedValue()) >= inputs.length)
+ {
+ out.clearSignals();
+ return;
+ }
+
+ ReadEnd active = inputs[selectValue];
+ out.feedSignals(active.getValues());
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ ArrayList<ReadEnd> wires = new ArrayList<>(Arrays.asList(inputs));
+ wires.add(select);
+ return Collections.unmodifiableList(wires);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components;
+
+import java.util.List;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreTriStateBuffer extends BasicCoreComponent
+{
+ ReadEnd in, enable;
+ ReadWriteEnd out;
+
+ public CoreTriStateBuffer(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out, ReadEnd enable)
+ {
+ super(timeline, processTime);
+ if (in.width() != out.width())
+ throw new IllegalArgumentException(
+ "Tri-state output must have the same amount of bits as the input. Input: " + in.width() + " Output: " + out.width());
+ if (enable.width() != 1)
+ throw new IllegalArgumentException("Tri-state enable must have exactly one bit, not " + enable.width() + ".");
+ this.in = in;
+ in.registerObserver(this);
+ this.enable = enable;
+ enable.registerObserver(this);
+ this.out = out;
+ }
+
+ @Override
+ protected void compute()
+ {
+ if (enable.getValue() == Bit.ONE)
+ out.feedSignals(in.getValues());
+ else
+ out.clearSignals();
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(in, enable);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+
+}
--- /dev/null
+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.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreUnidirectionalMerger extends CoreComponent implements LogicObserver
+{
+ private ReadWriteEnd out;
+ private ReadEnd[] inputs;
+ private int[] beginningIndex;
+
+ /**
+ *
+ * @param union The output of merging n {@link CoreWire}s into one. Must have width = a1.width() + a2.width() + ... + an.width().
+ * @param inputs The inputs to be merged into the union
+ */
+ public CoreUnidirectionalMerger(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<ReadEnd> getAllInputs()
+ {
+ return List.of(inputs);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+}
--- /dev/null
+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.types.BitVector;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreUnidirectionalSplitter extends CoreComponent implements LogicObserver
+{
+ private ReadEnd input;
+ private ReadWriteEnd[] outputs;
+
+ public CoreUnidirectionalSplitter(Timeline timeline, ReadEnd input, ReadWriteEnd... outputs)
+ {
+ super(timeline);
+ this.input = input;
+ this.outputs = outputs;
+ input.registerObserver(this);
+ int width = 0;
+ for (ReadEnd out : outputs)
+ width += out.width();
+
+ if (input.width() != width)
+ throw new IllegalArgumentException(
+ "The input of splitting one into n WireArrays must have width = a1.width() + a2.width() + ... + an.width().");
+ }
+
+ protected void compute()
+ {
+ BitVector inputBits = input.getValues();
+ int startIndex = 0;
+ for (int i = 0; i < outputs.length; i++)
+ {
+ outputs[i].feedSignals(inputBits.subVector(startIndex, startIndex + outputs[i].width()));
+ startIndex += outputs[i].width();
+ }
+ }
+
+ @Override
+ public void update(LogicObservable initiator)
+ {
+ compute();
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(input);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(outputs);
+ }
+}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.List;
-
-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;
-
-/**
- * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the
- * output.
- *
- * @author Fabian Stemmler
- *
- */
-public class Demux extends BasicComponent
-{
- private final ReadEnd select, in;
- private final ReadWriteEnd[] outputs;
- private final int outputSize;
- private int selected = -1;
-
- /**
- * Output {@link Wire}s and in must be of uniform width
- *
- * @param in Must be of uniform width with all outputs.
- * @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(Timeline timeline, int processTime, ReadEnd in, ReadEnd select, ReadWriteEnd... outputs)
- {
- super(timeline, processTime);
- outputSize = in.width();
-
- this.in = in;
- this.outputs = outputs;
- for (int i = 0; i < this.outputs.length; i++)
- {
- if (outputs[i].width() != outputSize)
- throw new IllegalArgumentException("All DEMUX wire arrays must be of uniform width!");
- this.outputs[i] = outputs[i];
- }
-
- this.select = select;
- select.registerObserver(this);
-
- int maxInputs = 1 << select.width();
- if (this.outputs.length > maxInputs)
- throw new IllegalArgumentException("There are more outputs (" + this.outputs.length + ") to the DEMUX than supported by "
- + select.width() + " select bits (" + maxInputs + ").");
- in.registerObserver(this);
- }
-
- @Override
- public void compute()
- {
- int selectValue = select.hasNumericValue() ? (int) select.getUnsignedValue() : -1;
- if (selectValue >= outputs.length)
- selectValue = -1;
-
- if (selected != selectValue && selected != -1)
- outputs[selected].clearSignals();
-
- selected = selectValue;
-
- if (selectValue != -1)
- outputs[selectValue].feedSignals(in.getValues());
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(in, select);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(outputs);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.ArrayList;
-import java.util.Collection;
-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.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-/**
- * This class models a simple on/off (ONE/ZERO) switch for user interaction.
- *
- * @author Christian Femers
- *
- */
-public class ManualSwitch extends Component implements LogicObservable
-{
- private Collection<LogicObserver> observers;
- private ReadWriteEnd output;
- private BitVector inputValues;
-
- public ManualSwitch(Timeline timeline, ReadWriteEnd output)
- {
- super(timeline);
- observers = new ArrayList<>();
- this.output = output;
- this.inputValues = output.getInputValues();
- }
-
- public void switchFullOn()
- {
- setState(BitVector.of(Bit.ONE, output.width()));
- }
-
- public void switchFullOff()
- {
- setState(BitVector.of(Bit.ZERO, output.width()));
- }
-
- public void toggle()
- {
- if (isFullOn())
- switchFullOff();
- else
- switchFullOn();
- }
-
- public void setState(Bit bit)
- {
- setState(BitVector.of(bit));
- }
-
- public void setState(BitVector bits)
- {
- if (bits.length() != output.width())
- throw new IllegalArgumentException("Incorrect bit vector length");
- if (bits.equals(inputValues))
- return;
- inputValues = bits;
- output.feedSignals(bits);
- notifyObservers();
- }
-
- public boolean isFullOn()
- {
- return BitVector.of(Bit.ONE, output.width()).equals(output.getInputValues());
- }
-
- public BitVector getValues()
- {
- return inputValues;
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of();
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(output);
- }
-
- @Override
- public void registerObserver(LogicObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(LogicObserver ob)
- {
- observers.remove(ob);
- }
-
- @Override
- public void notifyObservers()
- {
- observers.forEach(ob -> ob.update(this));
- }
-
-}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-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;
-
-/**
- * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the
- * output.
- *
- * @author Fabian Stemmler
- *
- */
-public class Mux extends BasicComponent
-{
- private ReadEnd select;
- private ReadWriteEnd out;
- private ReadEnd[] inputs;
- private final int outputSize;
-
- /**
- * Input {@link Wire}s and out must be of uniform width
- *
- * @param out Must be of uniform width with all inputs.
- * @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(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs)
- {
- super(timeline, processTime);
- outputSize = out.width();
-
- this.inputs = inputs.clone();
- for (int i = 0; i < this.inputs.length; i++)
- {
- if (inputs[i].width() != outputSize)
- throw new IllegalArgumentException("All MUX wire arrays must be of uniform width!");
- inputs[i].registerObserver(this);
- }
-
- this.select = select;
- select.registerObserver(this);
-
- int maxInputs = 1 << select.width();
- if (this.inputs.length > maxInputs)
- throw new IllegalArgumentException("There are more inputs (" + this.inputs.length + ") to the MUX than supported by "
- + select.width() + " select bits (" + maxInputs + ").");
-
- this.out = out;
- }
-
- public ReadEnd getOut()
- {
- return out;
- }
-
- public ReadEnd getSelect()
- {
- return select;
- }
-
- @Override
- public void compute()
- {
- int selectValue;
- if (!select.hasNumericValue() || (selectValue = (int) select.getUnsignedValue()) >= inputs.length)
- {
- out.clearSignals();
- return;
- }
-
- ReadEnd active = inputs[selectValue];
- out.feedSignals(active.getValues());
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- ArrayList<ReadEnd> wires = new ArrayList<>(Arrays.asList(inputs));
- wires.add(select);
- return Collections.unmodifiableList(wires);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components;
-
-import java.util.List;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class TriStateBuffer extends BasicComponent
-{
- ReadEnd in, enable;
- ReadWriteEnd out;
-
- public TriStateBuffer(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out, ReadEnd enable)
- {
- super(timeline, processTime);
- if (in.width() != out.width())
- throw new IllegalArgumentException(
- "Tri-state output must have the same amount of bits as the input. Input: " + in.width() + " Output: " + out.width());
- if (enable.width() != 1)
- throw new IllegalArgumentException("Tri-state enable must have exactly one bit, not " + enable.width() + ".");
- this.in = in;
- in.registerObserver(this);
- this.enable = enable;
- enable.registerObserver(this);
- this.out = out;
- }
-
- @Override
- protected void compute()
- {
- if (enable.getValue() == Bit.ONE)
- out.feedSignals(in.getValues());
- else
- out.clearSignals();
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(in, enable);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-
-}
+++ /dev/null
-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<ReadEnd> getAllInputs()
- {
- return List.of(inputs);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-}
+++ /dev/null
-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.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class UnidirectionalSplitter extends Component implements LogicObserver
-{
- private ReadEnd input;
- private ReadWriteEnd[] outputs;
-
- public UnidirectionalSplitter(Timeline timeline, ReadEnd input, ReadWriteEnd... outputs)
- {
- super(timeline);
- this.input = input;
- this.outputs = outputs;
- input.registerObserver(this);
- int width = 0;
- for (ReadEnd out : outputs)
- width += out.width();
-
- if (input.width() != width)
- throw new IllegalArgumentException(
- "The input of splitting one into n WireArrays must have width = a1.width() + a2.width() + ... + an.width().");
- }
-
- protected void compute()
- {
- BitVector inputBits = input.getValues();
- int startIndex = 0;
- for (int i = 0; i < outputs.length; i++)
- {
- outputs[i].feedSignals(inputBits.subVector(startIndex, startIndex + outputs[i].width()));
- startIndex += outputs[i].width();
- }
- }
-
- @Override
- public void update(LogicObservable initiator)
- {
- compute();
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(input);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(outputs);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class AndGate extends MultiInputGate
-{
- public AndGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime, BitVectorMutator::and, out, in);
- }
-}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreAndGate extends MultiInputCoreGate
+{
+ public CoreAndGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime, BitVectorMutator::and, out, in);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreNandGate extends MultiInputCoreGate
+{
+ public CoreNandGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime, BitVectorMutator::and, true, out, in);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreNorGate extends MultiInputCoreGate
+{
+ public CoreNorGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime, BitVectorMutator::or, true, out, in);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import java.util.List;
+
+import net.mograsim.logic.core.components.BasicCoreComponent;
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreNotGate extends BasicCoreComponent
+{
+ private ReadEnd in;
+ private ReadWriteEnd out;
+
+ public CoreNotGate(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out)
+ {
+ super(timeline, processTime);
+ this.in = in;
+ in.registerObserver(this);
+ this.out = out;
+ }
+
+ @Override
+ protected void compute()
+ {
+ out.feedSignals(in.getValues().not());
+ }
+
+ public ReadEnd getIn()
+ {
+ return in;
+ }
+
+ public ReadEnd getOut()
+ {
+ return out;
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(in);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public class CoreOrGate extends MultiInputCoreGate
+{
+ public CoreOrGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime, BitVectorMutator::or, out, in);
+ }
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+/**
+ * Outputs 1 when the number of 1 inputs is odd.
+ *
+ * @author Fabian Stemmler
+ */
+public class CoreXorGate extends MultiInputCoreGate
+{
+ public CoreXorGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime, BitVectorMutator::xor, out, in);
+ }
+
+}
--- /dev/null
+package net.mograsim.logic.core.components.gates;
+
+import java.util.List;
+
+import net.mograsim.logic.core.components.BasicCoreComponent;
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+import net.mograsim.logic.core.types.MutationOperation;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+public abstract class MultiInputCoreGate extends BasicCoreComponent
+{
+ protected ReadEnd[] in;
+ protected ReadWriteEnd out;
+ protected final int width;
+ protected MutationOperation op;
+ protected boolean invert = false;
+
+ protected MultiInputCoreGate(Timeline timeline, int processTime, MutationOperation op, ReadWriteEnd out, ReadEnd... in)
+ {
+ super(timeline, processTime);
+ this.op = op;
+ width = out.width();
+ this.in = in.clone();
+ if (in.length < 1)
+ throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length));
+ for (ReadEnd w : in)
+ {
+ if (w.width() != width)
+ throw new IllegalArgumentException("All wires connected to the gate must be of uniform length.");
+ w.registerObserver(this);
+ }
+ this.out = out;
+ }
+
+ protected MultiInputCoreGate(Timeline timeline, int processTime, MutationOperation op, boolean invert, ReadWriteEnd out, ReadEnd... in)
+ {
+ this(timeline, processTime, op, out, in);
+ this.invert = invert;
+ }
+
+ @Override
+ public List<ReadEnd> getAllInputs()
+ {
+ return List.of(in);
+ }
+
+ @Override
+ public List<ReadWriteEnd> getAllOutputs()
+ {
+ return List.of(out);
+ }
+
+ @Override
+ protected void compute()
+ {
+ BitVectorMutator mutator = BitVectorMutator.empty();
+ for (ReadEnd w : in)
+ op.apply(mutator, w.getValues());
+ out.feedSignals(invert ? mutator.toBitVector().not() : mutator.toBitVector());
+ }
+}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import java.util.List;
-
-import net.mograsim.logic.core.components.BasicComponent;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.types.MutationOperation;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public abstract class MultiInputGate extends BasicComponent
-{
- protected ReadEnd[] in;
- protected ReadWriteEnd out;
- protected final int width;
- protected MutationOperation op;
- protected boolean invert = false;
-
- protected MultiInputGate(Timeline timeline, int processTime, MutationOperation op, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime);
- this.op = op;
- width = out.width();
- this.in = in.clone();
- if (in.length < 1)
- throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length));
- for (ReadEnd w : in)
- {
- if (w.width() != width)
- throw new IllegalArgumentException("All wires connected to the gate must be of uniform length.");
- w.registerObserver(this);
- }
- this.out = out;
- }
-
- protected MultiInputGate(Timeline timeline, int processTime, MutationOperation op, boolean invert, ReadWriteEnd out, ReadEnd... in)
- {
- this(timeline, processTime, op, out, in);
- this.invert = invert;
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(in);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-
- @Override
- protected void compute()
- {
- BitVectorMutator mutator = BitVectorMutator.empty();
- for (ReadEnd w : in)
- op.apply(mutator, w.getValues());
- out.feedSignals(invert ? mutator.toBitVector().not() : mutator.toBitVector());
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class NandGate extends MultiInputGate
-{
- public NandGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime, BitVectorMutator::and, true, out, in);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class NorGate extends MultiInputGate
-{
- public NorGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime, BitVectorMutator::or, true, out, in);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import java.util.List;
-
-import net.mograsim.logic.core.components.BasicComponent;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class NotGate extends BasicComponent
-{
- private ReadEnd in;
- private ReadWriteEnd out;
-
- public NotGate(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out)
- {
- super(timeline, processTime);
- this.in = in;
- in.registerObserver(this);
- this.out = out;
- }
-
- @Override
- protected void compute()
- {
- out.feedSignals(in.getValues().not());
- }
-
- public ReadEnd getIn()
- {
- return in;
- }
-
- public ReadEnd getOut()
- {
- return out;
- }
-
- @Override
- public List<ReadEnd> getAllInputs()
- {
- return List.of(in);
- }
-
- @Override
- public List<ReadWriteEnd> getAllOutputs()
- {
- return List.of(out);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-public class OrGate extends MultiInputGate
-{
- public OrGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime, BitVectorMutator::or, out, in);
- }
-}
+++ /dev/null
-package net.mograsim.logic.core.components.gates;
-
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-/**
- * Outputs 1 when the number of 1 inputs is odd.
- *
- * @author Fabian Stemmler
- */
-public class XorGate extends MultiInputGate
-{
- public XorGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in)
- {
- super(timeline, processTime, BitVectorMutator::xor, out, in);
- }
-
-}
package net.mograsim.logic.core.types;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.preferences.ColorDefinition;
import net.mograsim.preferences.ColorDefinition.BuiltInColor;
import net.mograsim.preferences.Preferences;
--- /dev/null
+package net.mograsim.logic.core.wires;
+
+import static net.mograsim.logic.core.types.Bit.U;
+import static net.mograsim.logic.core.types.Bit.Z;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+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.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
+
+/**
+ * Represents an array of wires that can store n bits of information.
+ *
+ * @author Fabian Stemmler
+ *
+ */
+public class CoreWire
+{
+ public final String name;
+ private BitVector cachedValues;
+ public final int travelTime;
+ private List<ReadEnd> attached = new ArrayList<>();
+ public final int width;
+ List<ReadWriteEnd> inputs = new ArrayList<>();
+ Timeline timeline;
+ private Bit[] bitsWithoutFusions;
+ FusedBit[] fusedBits;
+
+ public CoreWire(Timeline timeline, int width, int travelTime)
+ {
+ this(timeline, width, travelTime, null);
+ }
+
+ public CoreWire(Timeline timeline, int width, int travelTime, String name)
+ {
+ if (width < 1)
+ throw new IllegalArgumentException(
+ String.format("Tried to create an array of wires with width %d, but a width of less than 1 makes no sense.", width));
+ this.name = name;
+ this.timeline = timeline;
+ this.width = width;
+ this.travelTime = travelTime;
+ initValues();
+ }
+
+ private void initValues()
+ {
+ cachedValues = U.toVector(width);
+ bitsWithoutFusions = cachedValues.getBits();
+ }
+
+ private void setNewValues(BitVector newValues)
+ {
+ cachedValues = newValues;
+ notifyObservers();
+ }
+
+ private void invalidateCachedValuesForAllFusedWires()
+ {
+ invalidateCachedValues();
+ if (fusedBits != null)
+ for (FusedBit fusion : fusedBits)
+ if (fusion != null)
+ fusion.invalidateCachedValuesForAllParticipatingWires();
+ }
+
+ private void invalidateCachedValues()
+ {
+ cachedValues = null;
+ notifyObservers();
+ }
+
+ void recalculateValuesWithoutFusions()
+ {
+ Bit[] bits = new Bit[width];
+ if (inputs.isEmpty())
+ Arrays.fill(bits, U);
+ else
+ {
+ System.arraycopy(inputs.get(0).getInputValues().getBits(), 0, bits, 0, width);
+ for (int i = 1; i < inputs.size(); i++)
+ Bit.join(bits, inputs.get(i).getInputValues().getBits());
+ }
+ bitsWithoutFusions = bits;
+ if (fusedBits == null)
+ setNewValues(BitVector.of(bits));
+ else
+ invalidateCachedValuesForAllFusedWires();
+ }
+
+ private void recalculatedCachedValues()
+ {
+ Bit[] bits;
+ if (fusedBits == null)
+ bits = bitsWithoutFusions;
+ else
+ {
+ bits = new Bit[width];
+ for (int i = 0; i < width; i++)
+ {
+ FusedBit fusion = fusedBits[i];
+ if (fusion == null)
+ bits[i] = bitsWithoutFusions[i];
+ else
+ bits[i] = fusion.getValue();
+ }
+ }
+ cachedValues = BitVector.of(bits);
+ }
+
+ /**
+ * Forces a Wire to take on specific values. If the new values differ from the old ones, the observers of the Wire will be notified.
+ * WARNING! Use this with care! The preferred way of writing the values is ReadWriteEnd.feedSignals(BitVector)
+ *
+ * @param values The values the <code>Wire</code> will have immediately after this method is called
+ */
+ public void forceValues(BitVector values)
+ {
+ setNewValues(values);
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as an unsigned integer with n bits.
+ *
+ * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the same
+ * value), not <code>Bit.U</code>, <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is returned otherwise.
+ *
+ * @author Fabian Stemmler
+ */
+ public boolean hasNumericValue()
+ {
+ return getValues().isBinary();
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as an unsigned integer with n bits.
+ *
+ * @return The unsigned value of the {@link CoreWire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+ *
+ * @author Fabian Stemmler
+ */
+ public long getUnsignedValue()
+ {
+ long val = 0;
+ long mask = 1;
+ for (Bit bit : getValues())
+ {
+ switch (bit)
+ {
+ default:
+ case Z:
+ case X:
+ return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0;
+ case ONE:
+ val |= mask;
+ break;
+ case ZERO:
+ }
+ mask = mask << 1;
+ }
+ return val;
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as a signed integer with n bits.
+ *
+ * @return The signed value of the {@link CoreWire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+ *
+ * @author Fabian Stemmler
+ */
+ public long getSignedValue()
+ {
+ long val = getUnsignedValue();
+ long mask = 1 << (width - 1);
+ if ((mask & val) != 0)
+ {
+ int shifts = 64 - width;
+ return (val << shifts) >> shifts;
+ }
+ return val;
+ }
+
+ /**
+ * Returns the least significant bit (LSB)
+ */
+ public Bit getValue()
+ {
+ return getValue(0);
+ }
+
+ /**
+ * Returns the least significant bit (LSB) of the given index
+ */
+ public Bit getValue(int index)
+ {
+ return getValues().getLSBit(index);
+ }
+
+ public BitVector getValues(int start, int end)
+ {
+ return getValues().subVector(start, end);
+ }
+
+ public BitVector getValues()
+ {
+ if (cachedValues == null)
+ recalculatedCachedValues();
+ return cachedValues;
+ }
+
+ /**
+ * Adds an {@link LogicObserver}, who will be notified when the value of the {@link CoreWire} is updated.
+ *
+ * @param ob The {@link LogicObserver} to be notified of changes.
+ * @return true if the given {@link LogicObserver} was not already registered, false otherwise
+ *
+ * @author Fabian Stemmler
+ */
+ boolean attachEnd(ReadEnd end)
+ {
+ return attached.add(end);
+ }
+
+ void detachEnd(ReadEnd end)
+ {
+ attached.remove(end);
+ }
+
+ private void notifyObservers()
+ {
+ attached.forEach(ReadEnd::update);
+ }
+
+ /**
+ * Create and register a {@link ReadWriteEnd} object, which is tied to this {@link CoreWire}. This {@link ReadWriteEnd} can be written to.
+ */
+ public ReadWriteEnd createReadWriteEnd()
+ {
+ return new ReadWriteEnd();
+ }
+
+ /**
+ * Create a {@link ReadEnd} object, which is tied to this {@link CoreWire}. This {@link ReadEnd} cannot be written to.
+ */
+ public ReadEnd createReadOnlyEnd()
+ {
+ return new ReadEnd();
+ }
+
+ void registerInput(ReadWriteEnd toRegister)
+ {
+ inputs.add(toRegister);
+ recalculateValuesWithoutFusions();
+ }
+
+ /**
+ * A {@link ReadEnd} feeds a constant signal into the {@link CoreWire} it is tied to. The combination of all inputs determines the
+ * {@link CoreWire}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 ReadEnd implements LogicObservable
+ {
+ private List<LogicObserver> observers = new ArrayList<>();
+
+ ReadEnd()
+ {
+ super();
+ CoreWire.this.attachEnd(this);
+ }
+
+ public void update()
+ {
+ notifyObservers();
+ }
+
+ /**
+ * Included for convenient use on {@link CoreWire}s of width 1.
+ *
+ * @return The value of bit 0.
+ *
+ * @author Fabian Stemmler
+ */
+ public Bit getValue()
+ {
+ return CoreWire.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 CoreWire.this.getValue(index);
+ }
+
+ public BitVector getValues()
+ {
+ return CoreWire.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 CoreWire.this.getValues(start, end);
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as an unsigned integer with n bits.
+ *
+ * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the
+ * same value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is returned otherwise.
+ *
+ * @author Fabian Stemmler
+ */
+ public boolean hasNumericValue()
+ {
+ return CoreWire.this.hasNumericValue();
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as an unsigned integer with n bits.
+ *
+ * @return The unsigned value of the {@link CoreWire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+ *
+ * @author Fabian Stemmler
+ */
+ public long getUnsignedValue()
+ {
+ return CoreWire.this.getUnsignedValue();
+ }
+
+ /**
+ * The {@link CoreWire} is interpreted as a signed integer with n bits.
+ *
+ * @return The signed value of the {@link CoreWire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+ *
+ * @author Fabian Stemmler
+ */
+ public long getSignedValue()
+ {
+ return CoreWire.this.getSignedValue();
+ }
+
+ @Override
+ public String toString()
+ {
+ return CoreWire.this.toString();
+ }
+
+ public void close()
+ {
+ inputs.remove(this);
+ detachEnd(this);
+ recalculateValuesWithoutFusions();
+ }
+
+ public int width()
+ {
+ return width;
+ }
+
+ public CoreWire getWire()
+ {
+ return CoreWire.this;
+ }
+
+ @Override
+ public void registerObserver(LogicObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(LogicObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+// void registerCloseObserver(LogicObserver ob)
+// {
+// closeObserver.add(ob);
+// }
+//
+// void deregisterCloseObserver(LogicObserver ob)
+// {
+// closeObserver.remove(ob);
+// }
+
+ @Override
+ public void notifyObservers()
+ {
+ observers.forEach(ob -> ob.update(this));
+ }
+ }
+
+ public class ReadWriteEnd extends ReadEnd
+ {
+ private boolean open;
+ private boolean isWriting;
+ private BitVector inputValues;
+
+ ReadWriteEnd()
+ {
+ super();
+ open = true;
+ isWriting = true;
+ initValues();
+ registerInput(this);
+ }
+
+ private void initValues()
+ {
+ inputValues = U.toVector(width);
+ }
+
+ /**
+ * Sets the wires values. This takes up time, as specified by the {@link CoreWire}s travel time.
+ *
+ * @param newValues The new values the wires should take on.
+ *
+ * @author Fabian Stemmler
+ */
+ public void feedSignals(Bit... newValues)
+ {
+ feedSignals(BitVector.of(newValues));
+ }
+
+ public void feedSignals(BitVector newValues)
+ {
+ if (newValues.length() != width)
+ throw new IllegalArgumentException(
+ String.format("Attempted to input %d bits instead of %d bits.", newValues.length(), width));
+ if (!open)
+ throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
+ timeline.addEvent(e -> setValues(newValues), travelTime);
+ }
+
+ /**
+ * Sets values of a subarray of wires. This takes up time, as specified by the {@link CoreWire}s travel time.
+ *
+ * @param bitVector 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, BitVector bitVector)
+ {
+ if (!open)
+ throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
+ timeline.addEvent(e -> setValues(startingBit, bitVector), travelTime);
+ }
+
+ /**
+ * Sets the values that are being fed into the {@link CoreWire}. 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))
+ {
+ Bit[] vals = inputValues.getBits();
+ System.arraycopy(newValues.getBits(), 0, vals, startingBit, newValues.length());
+ inputValues = BitVector.of(vals);
+ CoreWire.this.recalculateValuesWithoutFusions();
+ }
+ }
+
+ /**
+ * Sets the values that are being fed into the {@link CoreWire}. The preferred way of setting {@link ReadWriteEnd} values is via
+ * feedValues(...) with a delay.
+ */
+ void setValues(BitVector newValues)
+ {
+ if (inputValues.equals(newValues))
+ return;
+ inputValues = newValues;
+ CoreWire.this.recalculateValuesWithoutFusions();
+ }
+
+ /**
+ * @return The value (of bit 0) the {@link ReadEnd} is currently feeding into the associated {@link CoreWire}.Returns the least
+ * significant bit (LSB)
+ */
+ public Bit getInputValue()
+ {
+ return getInputValue(0);
+ }
+
+ /**
+ * @return The value which the {@link ReadEnd} is currently feeding into the associated {@link CoreWire} at the indexed {@link Bit}.
+ * Returns the least significant bit (LSB)
+ *
+ */
+ public Bit getInputValue(int index)
+ {
+ return inputValues.getLSBit(index);
+ }
+
+ /**
+ * @return A copy (safe to modify) of the values the {@link ReadEnd} is currently feeding into the associated {@link CoreWire}.
+ */
+ public BitVector getInputValues()
+ {
+ return inputValues;
+ }
+
+ public BitVector getInputValues(int start, int end)
+ {
+ return inputValues.subVector(start, end);
+ }
+
+ /**
+ * {@link ReadEnd} now feeds Z into the associated {@link CoreWire}.
+ */
+ public void clearSignals()
+ {
+ feedSignals(Z.toVector(width));
+ }
+
+ public BitVector wireValuesExcludingMe()
+ {
+ BitVectorMutator mutator = BitVectorMutator.empty();
+ boolean modified = false;
+ for (ReadWriteEnd wireEnd : inputs)
+ {
+ if (wireEnd == this)
+ continue;
+ modified = true;
+ mutator.join(wireEnd.inputValues);
+ }
+ if (!modified)
+ mutator.join(BitVector.of(Bit.Z, width));
+ return mutator.toBitVector();
+ }
+
+ @Override
+ public String toString()
+ {
+ return inputValues.toString();
+ }
+
+ @Override
+ public void close()
+ {
+ super.close();
+ open = false;
+ }
+
+ void setWriting(boolean isWriting)
+ {
+ if (this.isWriting != isWriting)
+ {
+ this.isWriting = isWriting;
+ if (isWriting)
+ inputs.add(this);
+ else
+ inputs.remove(this);
+ CoreWire.this.recalculateValuesWithoutFusions();
+ }
+ }
+
+ boolean isWriting()
+ {
+ return isWriting;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ String name = this.name == null ? String.format("0x%08x", hashCode()) : this.name;
+ return String.format("wire %s value: %s inputs: %s", name, getValues(), inputs);
+ }
+
+ public static ReadEnd[] extractEnds(CoreWire[] w)
+ {
+ ReadEnd[] inputs = new ReadEnd[w.length];
+ for (int i = 0; i < w.length; i++)
+ inputs[i] = w[i].createReadWriteEnd();
+ return inputs;
+ }
+
+ /**
+ *
+ * Fuses two wires together. If the bits change in one Wire, the other is changed accordingly immediately. Warning: The bits are
+ * permanently fused together.
+ *
+ * @param a The {@link CoreWire} to be fused with b
+ * @param b The {@link CoreWire} to be fused with a
+ */
+ public static void fuse(CoreWire a, CoreWire b)
+ {
+ fuse(a, b, 0, 0, a.width);
+ }
+
+ /**
+ * 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.
+ *
+ * @param a The {@link CoreWire} to be (partially) fused with b
+ * @param b The {@link CoreWire} to be (partially) fused with a
+ * @param fromA The first bit of {@link CoreWire} a to be fused
+ * @param fromB The first bit of {@link CoreWire} b to be fused
+ * @param width The amount of bits to fuse
+ */
+ public static void fuse(CoreWire a, CoreWire b, int fromA, int fromB, int width)
+ {
+ // iterate in this direction to be fail-fast (rely on the checks in fuse(Wire, Wire, int, int)
+ for (int i = width - 1; i >= 0; i--)
+ fuse(a, b, fromA + i, fromB + i);
+ }
+
+ /**
+ * Fuses one bit of two wires together. If this bit changes in one Wire, the other is changed accordingly immediately. Warning: The bits
+ * are permanently fused together.
+ *
+ * @param a The {@link CoreWire} to be (partially) fused with b
+ * @param b The {@link CoreWire} to be (partially) fused with a
+ * @param bitA The bit of {@link CoreWire} a to be fused
+ * @param bitB The bit of {@link CoreWire} b to be fused
+ */
+ public static void fuse(CoreWire a, CoreWire b, int bitA, int bitB)
+ {
+ if (bitA >= a.width)
+ throw new IllegalArgumentException("No bit " + bitA + " in " + a + " (width " + a.width + ")");
+ if (bitB >= b.width)
+ throw new IllegalArgumentException("No bit " + bitB + " in " + b + " (width " + b.width + ")");
+ if (a.fusedBits == null)
+ a.fusedBits = new FusedBit[a.width];
+ if (b.fusedBits == null)
+ b.fusedBits = new FusedBit[b.width];
+ FusedBit oldFusionA = a.fusedBits[bitA];
+ FusedBit oldFusionB = b.fusedBits[bitB];
+ if (oldFusionA == null)
+ if (oldFusionB == null)
+ {
+ FusedBit fusion = new FusedBit();
+ fusion.addParticipatingWireBit(a, bitA);
+ fusion.addParticipatingWireBit(b, bitB);
+ } else
+ oldFusionB.addParticipatingWireBit(a, bitA);
+ else if (oldFusionB == null)
+ oldFusionA.addParticipatingWireBit(b, bitB);
+ else
+ oldFusionA.mergeOtherIntoThis(oldFusionB);
+ }
+
+ private static class FusedBit
+ {
+ private final List<WireBit> participatingWireBits;
+
+ public FusedBit()
+ {
+ this.participatingWireBits = new ArrayList<>();
+ }
+
+ public void addParticipatingWireBit(CoreWire w, int bit)
+ {
+ addParticipatingWireBit(new WireBit(w, bit));
+ }
+
+ private void addParticipatingWireBit(WireBit wb)
+ {
+ wb.wire.fusedBits[wb.bit] = this;
+ participatingWireBits.add(wb);
+ wb.wire.invalidateCachedValuesForAllFusedWires();
+ }
+
+ public void mergeOtherIntoThis(FusedBit other)
+ {
+ for (WireBit wb : other.participatingWireBits)
+ addParticipatingWireBit(wb);
+ }
+
+ public void invalidateCachedValuesForAllParticipatingWires()
+ {
+ for (WireBit wb : participatingWireBits)
+ wb.wire.invalidateCachedValues();
+ }
+
+ public Bit getValue()
+ {
+ Bit result = null;
+ for (WireBit wb : participatingWireBits)
+ if (!wb.wire.inputs.isEmpty())
+ {
+ Bit bit = wb.wire.bitsWithoutFusions[wb.bit];
+ result = result == null ? bit : result.join(bit);
+ }
+ return result == null ? U : result;
+ }
+ }
+
+ private static class WireBit
+ {
+ public final CoreWire wire;
+ public final int bit;
+
+ public WireBit(CoreWire wire, int bit)
+ {
+ this.wire = wire;
+ this.bit = bit;
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.core.wires;
-
-import static net.mograsim.logic.core.types.Bit.U;
-import static net.mograsim.logic.core.types.Bit.Z;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-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.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
-
-/**
- * Represents an array of wires that can store n bits of information.
- *
- * @author Fabian Stemmler
- *
- */
-public class Wire
-{
- public final String name;
- private BitVector cachedValues;
- public final int travelTime;
- private List<ReadEnd> attached = new ArrayList<>();
- public final int width;
- List<ReadWriteEnd> inputs = new ArrayList<>();
- Timeline timeline;
- private Bit[] bitsWithoutFusions;
- FusedBit[] fusedBits;
-
- public Wire(Timeline timeline, int width, int travelTime)
- {
- this(timeline, width, travelTime, null);
- }
-
- public Wire(Timeline timeline, int width, int travelTime, String name)
- {
- if (width < 1)
- throw new IllegalArgumentException(
- String.format("Tried to create an array of wires with width %d, but a width of less than 1 makes no sense.", width));
- this.name = name;
- this.timeline = timeline;
- this.width = width;
- this.travelTime = travelTime;
- initValues();
- }
-
- private void initValues()
- {
- cachedValues = U.toVector(width);
- bitsWithoutFusions = cachedValues.getBits();
- }
-
- private void setNewValues(BitVector newValues)
- {
- cachedValues = newValues;
- notifyObservers();
- }
-
- private void invalidateCachedValuesForAllFusedWires()
- {
- invalidateCachedValues();
- if (fusedBits != null)
- for (FusedBit fusion : fusedBits)
- if (fusion != null)
- fusion.invalidateCachedValuesForAllParticipatingWires();
- }
-
- private void invalidateCachedValues()
- {
- cachedValues = null;
- notifyObservers();
- }
-
- void recalculateValuesWithoutFusions()
- {
- Bit[] bits = new Bit[width];
- if (inputs.isEmpty())
- Arrays.fill(bits, U);
- else
- {
- System.arraycopy(inputs.get(0).getInputValues().getBits(), 0, bits, 0, width);
- for (int i = 1; i < inputs.size(); i++)
- Bit.join(bits, inputs.get(i).getInputValues().getBits());
- }
- bitsWithoutFusions = bits;
- if (fusedBits == null)
- setNewValues(BitVector.of(bits));
- else
- invalidateCachedValuesForAllFusedWires();
- }
-
- private void recalculatedCachedValues()
- {
- Bit[] bits;
- if (fusedBits == null)
- bits = bitsWithoutFusions;
- else
- {
- bits = new Bit[width];
- for (int i = 0; i < width; i++)
- {
- FusedBit fusion = fusedBits[i];
- if (fusion == null)
- bits[i] = bitsWithoutFusions[i];
- else
- bits[i] = fusion.getValue();
- }
- }
- cachedValues = BitVector.of(bits);
- }
-
- /**
- * Forces a Wire to take on specific values. If the new values differ from the old ones, the observers of the Wire will be notified.
- * WARNING! Use this with care! The preferred way of writing the values is ReadWriteEnd.feedSignals(BitVector)
- *
- * @param values The values the <code>Wire</code> will have immediately after this method is called
- */
- public void forceValues(BitVector values)
- {
- setNewValues(values);
- }
-
- /**
- * The {@link Wire} is interpreted as an unsigned integer with n bits.
- *
- * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the same
- * value), not <code>Bit.U</code>, <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is returned otherwise.
- *
- * @author Fabian Stemmler
- */
- public boolean hasNumericValue()
- {
- return getValues().isBinary();
- }
-
- /**
- * 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()
- {
- long val = 0;
- long mask = 1;
- for (Bit bit : getValues())
- {
- switch (bit)
- {
- default:
- case Z:
- case X:
- return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0;
- case ONE:
- val |= mask;
- break;
- case ZERO:
- }
- mask = mask << 1;
- }
- return val;
- }
-
- /**
- * 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()
- {
- long val = getUnsignedValue();
- long mask = 1 << (width - 1);
- if ((mask & val) != 0)
- {
- int shifts = 64 - width;
- return (val << shifts) >> shifts;
- }
- return val;
- }
-
- /**
- * Returns the least significant bit (LSB)
- */
- public Bit getValue()
- {
- return getValue(0);
- }
-
- /**
- * Returns the least significant bit (LSB) of the given index
- */
- public Bit getValue(int index)
- {
- return getValues().getLSBit(index);
- }
-
- public BitVector getValues(int start, int end)
- {
- return getValues().subVector(start, end);
- }
-
- public BitVector getValues()
- {
- if (cachedValues == null)
- recalculatedCachedValues();
- return cachedValues;
- }
-
- /**
- * Adds an {@link LogicObserver}, who will be notified when the value of the {@link Wire} is updated.
- *
- * @param ob The {@link LogicObserver} to be notified of changes.
- * @return true if the given {@link LogicObserver} was not already registered, false otherwise
- *
- * @author Fabian Stemmler
- */
- boolean attachEnd(ReadEnd end)
- {
- return attached.add(end);
- }
-
- void detachEnd(ReadEnd end)
- {
- attached.remove(end);
- }
-
- private void notifyObservers()
- {
- attached.forEach(ReadEnd::update);
- }
-
- /**
- * Create and register a {@link ReadWriteEnd} object, which is tied to this {@link Wire}. This {@link ReadWriteEnd} can be written to.
- */
- public ReadWriteEnd createReadWriteEnd()
- {
- return new ReadWriteEnd();
- }
-
- /**
- * Create a {@link ReadEnd} object, which is tied to this {@link Wire}. This {@link ReadEnd} cannot be written to.
- */
- public ReadEnd createReadOnlyEnd()
- {
- return new ReadEnd();
- }
-
- void registerInput(ReadWriteEnd toRegister)
- {
- inputs.add(toRegister);
- recalculateValuesWithoutFusions();
- }
-
- /**
- * 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 ReadEnd implements LogicObservable
- {
- private List<LogicObserver> observers = new ArrayList<>();
-
- ReadEnd()
- {
- super();
- Wire.this.attachEnd(this);
- }
-
- public void update()
- {
- notifyObservers();
- }
-
- /**
- * Included for convenient use on {@link Wire}s of width 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);
- }
-
- 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 <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the
- * same value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> 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);
- recalculateValuesWithoutFusions();
- }
-
- public int width()
- {
- return width;
- }
-
- public Wire getWire()
- {
- return Wire.this;
- }
-
- @Override
- public void registerObserver(LogicObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(LogicObserver ob)
- {
- observers.remove(ob);
- }
-
-// void registerCloseObserver(LogicObserver ob)
-// {
-// closeObserver.add(ob);
-// }
-//
-// void deregisterCloseObserver(LogicObserver ob)
-// {
-// closeObserver.remove(ob);
-// }
-
- @Override
- public void notifyObservers()
- {
- observers.forEach(ob -> ob.update(this));
- }
- }
-
- public class ReadWriteEnd extends ReadEnd
- {
- private boolean open;
- private boolean isWriting;
- private BitVector inputValues;
-
- ReadWriteEnd()
- {
- super();
- open = true;
- isWriting = true;
- initValues();
- registerInput(this);
- }
-
- private void initValues()
- {
- inputValues = U.toVector(width);
- }
-
- /**
- * Sets the wires values. This takes up time, as specified by the {@link Wire}s travel time.
- *
- * @param newValues The new values the wires should take on.
- *
- * @author Fabian Stemmler
- */
- public void feedSignals(Bit... newValues)
- {
- feedSignals(BitVector.of(newValues));
- }
-
- public void feedSignals(BitVector newValues)
- {
- if (newValues.length() != width)
- throw new IllegalArgumentException(
- String.format("Attempted to input %d bits instead of %d bits.", newValues.length(), width));
- if (!open)
- throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
- timeline.addEvent(e -> setValues(newValues), travelTime);
- }
-
- /**
- * Sets values of a subarray of wires. This takes up time, as specified by the {@link Wire}s travel time.
- *
- * @param bitVector 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, BitVector bitVector)
- {
- if (!open)
- throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
- timeline.addEvent(e -> setValues(startingBit, bitVector), travelTime);
- }
-
- /**
- * 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))
- {
- Bit[] vals = inputValues.getBits();
- System.arraycopy(newValues.getBits(), 0, vals, startingBit, newValues.length());
- inputValues = BitVector.of(vals);
- Wire.this.recalculateValuesWithoutFusions();
- }
- }
-
- /**
- * 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;
- inputValues = newValues;
- Wire.this.recalculateValuesWithoutFusions();
- }
-
- /**
- * @return The value (of bit 0) the {@link ReadEnd} is currently feeding into the associated {@link Wire}.Returns the least
- * significant bit (LSB)
- */
- public Bit getInputValue()
- {
- return getInputValue(0);
- }
-
- /**
- * @return The value which the {@link ReadEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}.
- * Returns the least significant bit (LSB)
- *
- */
- public Bit getInputValue(int index)
- {
- return inputValues.getLSBit(index);
- }
-
- /**
- * @return A copy (safe to modify) of the values the {@link ReadEnd} is currently feeding into the associated {@link Wire}.
- */
- public BitVector getInputValues()
- {
- return inputValues;
- }
-
- public BitVector getInputValues(int start, int end)
- {
- return inputValues.subVector(start, end);
- }
-
- /**
- * {@link ReadEnd} now feeds Z into the associated {@link Wire}.
- */
- public void clearSignals()
- {
- feedSignals(Z.toVector(width));
- }
-
- public BitVector wireValuesExcludingMe()
- {
- BitVectorMutator mutator = BitVectorMutator.empty();
- boolean modified = false;
- for (ReadWriteEnd wireEnd : inputs)
- {
- if (wireEnd == this)
- continue;
- modified = true;
- mutator.join(wireEnd.inputValues);
- }
- if (!modified)
- mutator.join(BitVector.of(Bit.Z, width));
- return mutator.toBitVector();
- }
-
- @Override
- public String toString()
- {
- return inputValues.toString();
- }
-
- @Override
- public void close()
- {
- super.close();
- open = false;
- }
-
- void setWriting(boolean isWriting)
- {
- if (this.isWriting != isWriting)
- {
- this.isWriting = isWriting;
- if (isWriting)
- inputs.add(this);
- else
- inputs.remove(this);
- Wire.this.recalculateValuesWithoutFusions();
- }
- }
-
- boolean isWriting()
- {
- return isWriting;
- }
- }
-
- @Override
- public String toString()
- {
- String name = this.name == null ? String.format("0x%08x", hashCode()) : this.name;
- return String.format("wire %s value: %s inputs: %s", name, getValues(), inputs);
- }
-
- public static ReadEnd[] extractEnds(Wire[] w)
- {
- ReadEnd[] inputs = new ReadEnd[w.length];
- for (int i = 0; i < w.length; i++)
- inputs[i] = w[i].createReadWriteEnd();
- return inputs;
- }
-
- /**
- *
- * Fuses two wires together. If the bits change in one Wire, the other is changed accordingly immediately. Warning: The bits are
- * permanently fused together.
- *
- * @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.width);
- }
-
- /**
- * 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.
- *
- * @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 width The amount of bits to fuse
- */
- public static void fuse(Wire a, Wire b, int fromA, int fromB, int width)
- {
- // iterate in this direction to be fail-fast (rely on the checks in fuse(Wire, Wire, int, int)
- for (int i = width - 1; i >= 0; i--)
- fuse(a, b, fromA + i, fromB + i);
- }
-
- /**
- * Fuses one bit of two wires together. If this bit changes in one Wire, the other is changed accordingly immediately. Warning: The bits
- * are permanently fused together.
- *
- * @param a The {@link Wire} to be (partially) fused with b
- * @param b The {@link Wire} to be (partially) fused with a
- * @param bitA The bit of {@link Wire} a to be fused
- * @param bitB The bit of {@link Wire} b to be fused
- */
- public static void fuse(Wire a, Wire b, int bitA, int bitB)
- {
- if (bitA >= a.width)
- throw new IllegalArgumentException("No bit " + bitA + " in " + a + " (width " + a.width + ")");
- if (bitB >= b.width)
- throw new IllegalArgumentException("No bit " + bitB + " in " + b + " (width " + b.width + ")");
- if (a.fusedBits == null)
- a.fusedBits = new FusedBit[a.width];
- if (b.fusedBits == null)
- b.fusedBits = new FusedBit[b.width];
- FusedBit oldFusionA = a.fusedBits[bitA];
- FusedBit oldFusionB = b.fusedBits[bitB];
- if (oldFusionA == null)
- if (oldFusionB == null)
- {
- FusedBit fusion = new FusedBit();
- fusion.addParticipatingWireBit(a, bitA);
- fusion.addParticipatingWireBit(b, bitB);
- } else
- oldFusionB.addParticipatingWireBit(a, bitA);
- else if (oldFusionB == null)
- oldFusionA.addParticipatingWireBit(b, bitB);
- else
- oldFusionA.mergeOtherIntoThis(oldFusionB);
- }
-
- private static class FusedBit
- {
- private final List<WireBit> participatingWireBits;
-
- public FusedBit()
- {
- this.participatingWireBits = new ArrayList<>();
- }
-
- public void addParticipatingWireBit(Wire w, int bit)
- {
- addParticipatingWireBit(new WireBit(w, bit));
- }
-
- private void addParticipatingWireBit(WireBit wb)
- {
- wb.wire.fusedBits[wb.bit] = this;
- participatingWireBits.add(wb);
- wb.wire.invalidateCachedValuesForAllFusedWires();
- }
-
- public void mergeOtherIntoThis(FusedBit other)
- {
- for (WireBit wb : other.participatingWireBits)
- addParticipatingWireBit(wb);
- }
-
- public void invalidateCachedValuesForAllParticipatingWires()
- {
- for (WireBit wb : participatingWireBits)
- wb.wire.invalidateCachedValues();
- }
-
- public Bit getValue()
- {
- Bit result = null;
- for (WireBit wb : participatingWireBits)
- if (!wb.wire.inputs.isEmpty())
- {
- Bit bit = wb.wire.bitsWithoutFusions[wb.bit];
- result = result == null ? bit : result.join(bit);
- }
- return result == null ? U : result;
- }
- }
-
- private static class WireBit
- {
- public final Wire wire;
- public final int bit;
-
- public WireBit(Wire wire, int bit)
- {
- this.wire = wire;
- this.bit = bit;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.core.tests;
-
-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 org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import net.mograsim.logic.core.components.Demux;
-import net.mograsim.logic.core.components.Mux;
-import net.mograsim.logic.core.components.TriStateBuffer;
-import net.mograsim.logic.core.components.UnidirectionalMerger;
-import net.mograsim.logic.core.components.UnidirectionalSplitter;
-import net.mograsim.logic.core.components.gates.AndGate;
-import net.mograsim.logic.core.components.gates.NandGate;
-import net.mograsim.logic.core.components.gates.NorGate;
-import net.mograsim.logic.core.components.gates.NotGate;
-import net.mograsim.logic.core.components.gates.OrGate;
-import net.mograsim.logic.core.components.gates.XorGate;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-
-@SuppressWarnings("unused")
-class ComponentTest
-{
- private Timeline t = new Timeline(11);
-
- @BeforeEach
- void resetTimeline()
- {
- t.reset();
- }
-
- @Test
- void circuitExampleTest()
- {
- Wire a = new Wire(t, 1, 1), b = new Wire(t, 1, 1), c = new Wire(t, 1, 10), d = new Wire(t, 2, 1), e = new Wire(t, 1, 1),
- f = new Wire(t, 1, 1), g = new Wire(t, 1, 1), h = new Wire(t, 2, 1), i = new Wire(t, 2, 1), j = new Wire(t, 1, 1),
- k = new Wire(t, 1, 1);
- new AndGate(t, 1, f.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
- new NotGate(t, 1, f.createReadOnlyEnd(), g.createReadWriteEnd());
- new UnidirectionalMerger(t, h.createReadWriteEnd(), c.createReadOnlyEnd(), g.createReadOnlyEnd());
- new Mux(t, 1, i.createReadWriteEnd(), e.createReadOnlyEnd(), h.createReadOnlyEnd(), d.createReadOnlyEnd());
- new UnidirectionalSplitter(t, i.createReadOnlyEnd(), k.createReadWriteEnd(), j.createReadWriteEnd());
-
- a.createReadWriteEnd().feedSignals(Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ONE);
- c.createReadWriteEnd().feedSignals(Bit.ZERO);
- d.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE);
- e.createReadWriteEnd().feedSignals(Bit.ZERO);
-
- t.executeAll();
-
- assertEquals(Bit.ONE, j.getValue());
- assertEquals(Bit.ZERO, k.getValue());
- }
-
- @Test
- void splitterTest()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 2, 1), c = new Wire(t, 3, 1), in = new Wire(t, 8, 1);
- in.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- new UnidirectionalSplitter(t, in.createReadOnlyEnd(), a.createReadWriteEnd(), b.createReadWriteEnd(), c.createReadWriteEnd());
-
- t.executeAll();
-
- assertBitArrayEquals(a.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);
- assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO);
- assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);
- }
-
- @Test
- void mergerTest()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 2, 1), c = new Wire(t, 3, 1), out = new Wire(t, 8, 1);
- a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO);
- c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
-
- new UnidirectionalMerger(t, out.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
-
- t.executeAll();
-
- assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- }
-
- @Test
- void fusionTest1()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 2, 1), c = new Wire(t, 3, 1), out = new Wire(t, 8, 1);
- Wire.fuse(a, out, 0, 0, a.width);
- Wire.fuse(b, out, 0, a.width, b.width);
- Wire.fuse(c, out, 0, a.width + b.width, c.width);
- ReadWriteEnd rA = a.createReadWriteEnd();
- rA.feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);
- ReadWriteEnd rB = b.createReadWriteEnd();
- rB.feedSignals(Bit.ONE, Bit.ZERO);
- ReadWriteEnd rC = c.createReadWriteEnd();
- rC.feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
-
- t.executeAll();
- assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- out.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
- t.executeAll();
- assertBitArrayEquals(rA.getValues(), Bit.X, Bit.X, Bit.X);
- assertBitArrayEquals(rB.getValues(), Bit.X, Bit.X);
- assertBitArrayEquals(rC.getValues(), Bit.X, Bit.X, Bit.X);
- rA.clearSignals();
- rB.clearSignals();
- rC.clearSignals();
- t.executeAll();
- assertBitArrayEquals(rA.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);
- assertBitArrayEquals(rB.getValues(), Bit.ZERO, Bit.ONE);
- assertBitArrayEquals(rC.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);
- }
-
- @Test
- void fusionTest2()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 1);
- Wire.fuse(a, b);
- ReadWriteEnd rw = a.createReadWriteEnd();
- t.executeAll();
- assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
-
- rw.feedSignals(Bit.ONE, Bit.U, Bit.Z);
- t.executeAll();
- assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.U, Bit.Z);
- }
-
- @Test
- void fusionTest3()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 1);
- a.createReadWriteEnd().feedSignals(Bit.Z, Bit.U, Bit.X);
- t.executeAll();
- Wire.fuse(a, b);
- t.executeAll();
- assertBitArrayEquals(b.getValues(), Bit.Z, Bit.U, Bit.X);
- }
-
- @Test
- void fusionTest4()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 1);
- a.createReadWriteEnd();
- t.executeAll();
-
- Wire.fuse(a, b);
- t.executeAll();
- assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
- }
-
-// @Test
-// void connectorTest()
-// {
-// t.reset();
-// Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 1);
-// new Connector(t, a.createReadWriteEnd(), b.createReadWriteEnd()).connect();
-//// b.createReadWriteEnd();
-// a.createReadWriteEnd();
-// t.executeAll();
-// assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
-// }
-
- @Test
- void triStateBufferTest()
- {
- Wire a = new Wire(t, 1, 1), b = new Wire(t, 1, 1), en = new Wire(t, 1, 1), notEn = new Wire(t, 1, 1);
- new NotGate(t, 1, en.createReadOnlyEnd(), notEn.createReadWriteEnd());
- new TriStateBuffer(t, 1, a.createReadOnlyEnd(), b.createReadWriteEnd(), en.createReadOnlyEnd());
- new TriStateBuffer(t, 1, b.createReadOnlyEnd(), a.createReadWriteEnd(), notEn.createReadOnlyEnd());
-
- ReadWriteEnd enI = en.createReadWriteEnd(), aI = a.createReadWriteEnd(), bI = b.createReadWriteEnd();
- enI.feedSignals(Bit.ONE);
- aI.feedSignals(Bit.ONE);
- bI.feedSignals(Bit.Z);
-
- t.executeAll();
-
- assertEquals(Bit.ONE, b.getValue());
-
- bI.feedSignals(Bit.ZERO);
-
- t.executeAll();
-
- assertEquals(Bit.X, b.getValue());
- assertEquals(Bit.ONE, a.getValue());
-
- aI.clearSignals();
- enI.feedSignals(Bit.ZERO);
-
- t.executeAll();
-
- assertEquals(Bit.ZERO, a.getValue());
-
- }
-
- @Test
- void muxTest()
- {
- Wire a = new Wire(t, 4, 3), b = new Wire(t, 4, 6), c = new Wire(t, 4, 4), select = new Wire(t, 2, 5), out = new Wire(t, 4, 1);
- ReadWriteEnd selectIn = select.createReadWriteEnd();
-
- selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
- c.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
-
- new Mux(t, 1, out.createReadWriteEnd(), select.createReadOnlyEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(),
- c.createReadOnlyEnd());
- t.executeAll();
-
- assertBitArrayEquals(out.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
- selectIn.feedSignals(Bit.ZERO, Bit.ONE);
- t.executeAll();
-
- assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
-
- selectIn.feedSignals(Bit.ONE, Bit.ONE);
- t.executeAll();
-
- assertBitArrayEquals(out.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
-
- }
-
- @Test
- void demuxTest()
- {
- Wire a = new Wire(t, 4, 3), b = new Wire(t, 4, 6), c = new Wire(t, 4, 4), select = new Wire(t, 2, 5), in = new Wire(t, 4, 1);
- ReadWriteEnd selectIn = select.createReadWriteEnd();
-
- selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
- in.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
-
- new Demux(t, 1, in.createReadOnlyEnd(), select.createReadOnlyEnd(), a.createReadWriteEnd(), b.createReadWriteEnd(),
- c.createReadWriteEnd());
- t.executeAll();
-
- assertBitArrayEquals(a.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
- assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
- assertBitArrayEquals(c.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
- selectIn.feedSignals(Bit.ZERO, Bit.ONE);
- t.executeAll();
-
- assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
- assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
- assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
-
- selectIn.feedSignals(Bit.ONE, Bit.ONE);
- t.executeAll();
-
- assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
- assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
- assertBitArrayEquals(c.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
-
- }
-
- @Test
- void andTest()
- {
- Wire a = new Wire(t, 4, 1), b = new Wire(t, 4, 3), c = new Wire(t, 4, 1);
- new AndGate(t, 1, c.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
-
- t.executeAll();
-
- assertBitArrayEquals(c.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO);
- }
-
- @Test
- void orTest()
- {
- Wire a = new Wire(t, 4, 1), b = new Wire(t, 4, 3), c = new Wire(t, 4, 1);
- new OrGate(t, 1, c.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
-
- t.executeAll();
-
- assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);
- }
-
- @Test
- void nandTest()
- {
- Wire a = new Wire(t, 4, 1), b = new Wire(t, 4, 3), c = new Wire(t, 4, 1), d = new Wire(t, 4, 1);
- new NandGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
-
- t.executeAll();
-
- assertBitArrayEquals(d.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ONE);
- }
-
- @Test
- void norTest()
- {
- Wire a = new Wire(t, 4, 1), b = new Wire(t, 4, 3), c = new Wire(t, 4, 1), d = new Wire(t, 4, 1);
- new NorGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
- b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
-
- t.executeAll();
-
- assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ZERO, Bit.ONE, Bit.ZERO);
- }
-
- @Test
- void xorTest()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 2), c = new Wire(t, 3, 1), d = new Wire(t, 3, 1);
- new XorGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
- a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);
- b.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
- c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
-
- t.executeAll();
-
- assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE);
- }
-
- @Test
- void notTest()
- {
- Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 2);
- new NotGate(t, 1, a.createReadOnlyEnd(), b.createReadWriteEnd());
- a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);
-
- t.executeAll();
-
- assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO, Bit.ZERO);
- }
-
- @Test
- void rsLatchCircuitTest()
- {
- Wire r = new Wire(t, 1, 1), s = new Wire(t, 1, 1), t1 = new Wire(t, 1, 15), t2 = new Wire(t, 1, 1), q = new Wire(t, 1, 1),
- nq = new Wire(t, 1, 1);
-
- new OrGate(t, 1, t2.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd());
- new OrGate(t, 1, t1.createReadWriteEnd(), s.createReadOnlyEnd(), q.createReadOnlyEnd());
- new NotGate(t, 1, t2.createReadOnlyEnd(), q.createReadWriteEnd());
- new NotGate(t, 1, t1.createReadOnlyEnd(), nq.createReadWriteEnd());
-
- ReadWriteEnd sIn = s.createReadWriteEnd(), rIn = r.createReadWriteEnd();
-
- sIn.feedSignals(Bit.ONE);
- rIn.feedSignals(Bit.ZERO);
-
- t.executeAll();
-
- assertEquals(Bit.ONE, q.getValue());
- assertEquals(Bit.ZERO, nq.getValue());
-
- sIn.feedSignals(Bit.ZERO);
-
- t.executeAll();
- assertEquals(Bit.ONE, q.getValue());
- assertEquals(Bit.ZERO, nq.getValue());
-
- rIn.feedSignals(Bit.ONE);
-
- t.executeAll();
-
- assertEquals(Bit.ZERO, q.getValue());
- assertEquals(Bit.ONE, nq.getValue());
- }
-
- @Test
- void numericValueTest()
- {
- Wire a = new Wire(t, 4, 1);
- a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE);
-
- t.executeAll();
-
- assertEquals(15, a.getUnsignedValue());
- assertEquals(-1, a.getSignedValue());
- }
-
- boolean flag = false;
-
- @Test
- void simpleTimelineTest()
- {
- Timeline t = new Timeline(3);
- flag = false;
- t.addEvent((e) ->
- {
- if (!flag)
- fail("Events executed out of order!");
- flag = false;
- }, 15);
- t.addEvent((e) ->
- {
- if (flag)
- fail("Events executed out of order!");
- flag = true;
- }, 10);
- t.addEvent((e) ->
- {
- if (flag)
- fail("Events executed out of order!");
- flag = true;
- }, 20);
- t.addEvent((e) ->
- {
- fail("Only supposed to execute until timestamp 20, not 25");
- }, 25);
-
- t.executeUntil(t.laterThan(20), 100);
-
- if (!flag)
- fail("Not all events were executed in order!");
- }
-
- // TODO: Adapt this test, now that update notifications are issued whenever any input to a wire changes
- @Disabled("Out of date")
- @Test
- void multipleInputs()
- {
- Wire w = new Wire(t, 2, 1);
- ReadWriteEnd wI1 = w.createReadWriteEnd(), wI2 = w.createReadWriteEnd();
- wI1.feedSignals(Bit.ONE, Bit.Z);
- wI2.feedSignals(Bit.Z, Bit.X);
- t.executeAll();
- assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.X);
-
- wI2.feedSignals(Bit.ZERO, Bit.Z);
- t.executeAll();
- assertBitArrayEquals(w.getValues(), Bit.X, Bit.Z);
-
- wI2.feedSignals(Bit.Z, Bit.Z);
- t.executeAll();
- assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
-
- wI2.feedSignals(Bit.ONE, Bit.Z);
- ReadEnd rE = w.createReadOnlyEnd();
- rE.registerObserver((i) -> fail("WireEnd notified observer, although value did not change."));
- t.executeAll();
- rE.close();
- wI1.feedSignals(Bit.X, Bit.X);
- t.executeAll();
- wI1.registerObserver((i) -> fail("WireEnd notified observer, although it was closed."));
- wI1.close();
- assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
- }
-
- private static void assertBitArrayEquals(BitVector actual, Bit... expected)
- {
- assertArrayEquals(expected, actual.getBits());
- }
-}
--- /dev/null
+package net.mograsim.logic.core.tests;
+
+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 org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import net.mograsim.logic.core.components.CoreDemux;
+import net.mograsim.logic.core.components.CoreMux;
+import net.mograsim.logic.core.components.CoreTriStateBuffer;
+import net.mograsim.logic.core.components.CoreUnidirectionalMerger;
+import net.mograsim.logic.core.components.CoreUnidirectionalSplitter;
+import net.mograsim.logic.core.components.gates.CoreAndGate;
+import net.mograsim.logic.core.components.gates.CoreNandGate;
+import net.mograsim.logic.core.components.gates.CoreNorGate;
+import net.mograsim.logic.core.components.gates.CoreNotGate;
+import net.mograsim.logic.core.components.gates.CoreOrGate;
+import net.mograsim.logic.core.components.gates.CoreXorGate;
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
+
+@SuppressWarnings("unused")
+class CoreComponentTest
+{
+ private Timeline t = new Timeline(11);
+
+ @BeforeEach
+ void resetTimeline()
+ {
+ t.reset();
+ }
+
+ @Test
+ void circuitExampleTest()
+ {
+ CoreWire a = new CoreWire(t, 1, 1), b = new CoreWire(t, 1, 1), c = new CoreWire(t, 1, 10), d = new CoreWire(t, 2, 1), e = new CoreWire(t, 1, 1),
+ f = new CoreWire(t, 1, 1), g = new CoreWire(t, 1, 1), h = new CoreWire(t, 2, 1), i = new CoreWire(t, 2, 1), j = new CoreWire(t, 1, 1),
+ k = new CoreWire(t, 1, 1);
+ new CoreAndGate(t, 1, f.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
+ new CoreNotGate(t, 1, f.createReadOnlyEnd(), g.createReadWriteEnd());
+ new CoreUnidirectionalMerger(t, h.createReadWriteEnd(), c.createReadOnlyEnd(), g.createReadOnlyEnd());
+ new CoreMux(t, 1, i.createReadWriteEnd(), e.createReadOnlyEnd(), h.createReadOnlyEnd(), d.createReadOnlyEnd());
+ new CoreUnidirectionalSplitter(t, i.createReadOnlyEnd(), k.createReadWriteEnd(), j.createReadWriteEnd());
+
+ a.createReadWriteEnd().feedSignals(Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ONE);
+ c.createReadWriteEnd().feedSignals(Bit.ZERO);
+ d.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE);
+ e.createReadWriteEnd().feedSignals(Bit.ZERO);
+
+ t.executeAll();
+
+ assertEquals(Bit.ONE, j.getValue());
+ assertEquals(Bit.ZERO, k.getValue());
+ }
+
+ @Test
+ void splitterTest()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 2, 1), c = new CoreWire(t, 3, 1), in = new CoreWire(t, 8, 1);
+ in.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+ new CoreUnidirectionalSplitter(t, in.createReadOnlyEnd(), a.createReadWriteEnd(), b.createReadWriteEnd(), c.createReadWriteEnd());
+
+ t.executeAll();
+
+ assertBitArrayEquals(a.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);
+ assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO);
+ assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);
+ }
+
+ @Test
+ void mergerTest()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 2, 1), c = new CoreWire(t, 3, 1), out = new CoreWire(t, 8, 1);
+ a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO);
+ c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ new CoreUnidirectionalMerger(t, out.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
+
+ t.executeAll();
+
+ assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+ }
+
+ @Test
+ void fusionTest1()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 2, 1), c = new CoreWire(t, 3, 1), out = new CoreWire(t, 8, 1);
+ CoreWire.fuse(a, out, 0, 0, a.width);
+ CoreWire.fuse(b, out, 0, a.width, b.width);
+ CoreWire.fuse(c, out, 0, a.width + b.width, c.width);
+ ReadWriteEnd rA = a.createReadWriteEnd();
+ rA.feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);
+ ReadWriteEnd rB = b.createReadWriteEnd();
+ rB.feedSignals(Bit.ONE, Bit.ZERO);
+ ReadWriteEnd rC = c.createReadWriteEnd();
+ rC.feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ t.executeAll();
+ assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+ out.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+ t.executeAll();
+ assertBitArrayEquals(rA.getValues(), Bit.X, Bit.X, Bit.X);
+ assertBitArrayEquals(rB.getValues(), Bit.X, Bit.X);
+ assertBitArrayEquals(rC.getValues(), Bit.X, Bit.X, Bit.X);
+ rA.clearSignals();
+ rB.clearSignals();
+ rC.clearSignals();
+ t.executeAll();
+ assertBitArrayEquals(rA.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);
+ assertBitArrayEquals(rB.getValues(), Bit.ZERO, Bit.ONE);
+ assertBitArrayEquals(rC.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);
+ }
+
+ @Test
+ void fusionTest2()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 3, 1);
+ CoreWire.fuse(a, b);
+ ReadWriteEnd rw = a.createReadWriteEnd();
+ t.executeAll();
+ assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
+
+ rw.feedSignals(Bit.ONE, Bit.U, Bit.Z);
+ t.executeAll();
+ assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.U, Bit.Z);
+ }
+
+ @Test
+ void fusionTest3()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 3, 1);
+ a.createReadWriteEnd().feedSignals(Bit.Z, Bit.U, Bit.X);
+ t.executeAll();
+ CoreWire.fuse(a, b);
+ t.executeAll();
+ assertBitArrayEquals(b.getValues(), Bit.Z, Bit.U, Bit.X);
+ }
+
+ @Test
+ void fusionTest4()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 3, 1);
+ a.createReadWriteEnd();
+ t.executeAll();
+
+ CoreWire.fuse(a, b);
+ t.executeAll();
+ assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
+ }
+
+// @Test
+// void connectorTest()
+// {
+// t.reset();
+// Wire a = new Wire(t, 3, 1), b = new Wire(t, 3, 1);
+// new Connector(t, a.createReadWriteEnd(), b.createReadWriteEnd()).connect();
+//// b.createReadWriteEnd();
+// a.createReadWriteEnd();
+// t.executeAll();
+// assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U);
+// }
+
+ @Test
+ void triStateBufferTest()
+ {
+ CoreWire a = new CoreWire(t, 1, 1), b = new CoreWire(t, 1, 1), en = new CoreWire(t, 1, 1), notEn = new CoreWire(t, 1, 1);
+ new CoreNotGate(t, 1, en.createReadOnlyEnd(), notEn.createReadWriteEnd());
+ new CoreTriStateBuffer(t, 1, a.createReadOnlyEnd(), b.createReadWriteEnd(), en.createReadOnlyEnd());
+ new CoreTriStateBuffer(t, 1, b.createReadOnlyEnd(), a.createReadWriteEnd(), notEn.createReadOnlyEnd());
+
+ ReadWriteEnd enI = en.createReadWriteEnd(), aI = a.createReadWriteEnd(), bI = b.createReadWriteEnd();
+ enI.feedSignals(Bit.ONE);
+ aI.feedSignals(Bit.ONE);
+ bI.feedSignals(Bit.Z);
+
+ t.executeAll();
+
+ assertEquals(Bit.ONE, b.getValue());
+
+ bI.feedSignals(Bit.ZERO);
+
+ t.executeAll();
+
+ assertEquals(Bit.X, b.getValue());
+ assertEquals(Bit.ONE, a.getValue());
+
+ aI.clearSignals();
+ enI.feedSignals(Bit.ZERO);
+
+ t.executeAll();
+
+ assertEquals(Bit.ZERO, a.getValue());
+
+ }
+
+ @Test
+ void muxTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 3), b = new CoreWire(t, 4, 6), c = new CoreWire(t, 4, 4), select = new CoreWire(t, 2, 5), out = new CoreWire(t, 4, 1);
+ ReadWriteEnd selectIn = select.createReadWriteEnd();
+
+ selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+ c.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ new CoreMux(t, 1, out.createReadWriteEnd(), select.createReadOnlyEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(),
+ c.createReadOnlyEnd());
+ t.executeAll();
+
+ assertBitArrayEquals(out.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+ selectIn.feedSignals(Bit.ZERO, Bit.ONE);
+ t.executeAll();
+
+ assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ selectIn.feedSignals(Bit.ONE, Bit.ONE);
+ t.executeAll();
+
+ assertBitArrayEquals(out.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
+
+ }
+
+ @Test
+ void demuxTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 3), b = new CoreWire(t, 4, 6), c = new CoreWire(t, 4, 4), select = new CoreWire(t, 2, 5), in = new CoreWire(t, 4, 1);
+ ReadWriteEnd selectIn = select.createReadWriteEnd();
+
+ selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
+ in.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+
+ new CoreDemux(t, 1, in.createReadOnlyEnd(), select.createReadOnlyEnd(), a.createReadWriteEnd(), b.createReadWriteEnd(),
+ c.createReadWriteEnd());
+ t.executeAll();
+
+ assertBitArrayEquals(a.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+ assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
+ assertBitArrayEquals(c.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
+ selectIn.feedSignals(Bit.ZERO, Bit.ONE);
+ t.executeAll();
+
+ assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
+ assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
+ assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
+
+ selectIn.feedSignals(Bit.ONE, Bit.ONE);
+ t.executeAll();
+
+ assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
+ assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);
+ assertBitArrayEquals(c.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);
+
+ }
+
+ @Test
+ void andTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 1), b = new CoreWire(t, 4, 3), c = new CoreWire(t, 4, 1);
+ new CoreAndGate(t, 1, c.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ t.executeAll();
+
+ assertBitArrayEquals(c.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO);
+ }
+
+ @Test
+ void orTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 1), b = new CoreWire(t, 4, 3), c = new CoreWire(t, 4, 1);
+ new CoreOrGate(t, 1, c.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ t.executeAll();
+
+ assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);
+ }
+
+ @Test
+ void nandTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 1), b = new CoreWire(t, 4, 3), c = new CoreWire(t, 4, 1), d = new CoreWire(t, 4, 1);
+ new CoreNandGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+ c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+
+ t.executeAll();
+
+ assertBitArrayEquals(d.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ONE);
+ }
+
+ @Test
+ void norTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 1), b = new CoreWire(t, 4, 3), c = new CoreWire(t, 4, 1), d = new CoreWire(t, 4, 1);
+ new CoreNorGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+ b.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
+ c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);
+
+ t.executeAll();
+
+ assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ZERO, Bit.ONE, Bit.ZERO);
+ }
+
+ @Test
+ void xorTest()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 3, 2), c = new CoreWire(t, 3, 1), d = new CoreWire(t, 3, 1);
+ new CoreXorGate(t, 1, d.createReadWriteEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);
+ b.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
+ c.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
+
+ t.executeAll();
+
+ assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE);
+ }
+
+ @Test
+ void notTest()
+ {
+ CoreWire a = new CoreWire(t, 3, 1), b = new CoreWire(t, 3, 2);
+ new CoreNotGate(t, 1, a.createReadOnlyEnd(), b.createReadWriteEnd());
+ a.createReadWriteEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);
+
+ t.executeAll();
+
+ assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO, Bit.ZERO);
+ }
+
+ @Test
+ void rsLatchCircuitTest()
+ {
+ CoreWire r = new CoreWire(t, 1, 1), s = new CoreWire(t, 1, 1), t1 = new CoreWire(t, 1, 15), t2 = new CoreWire(t, 1, 1), q = new CoreWire(t, 1, 1),
+ nq = new CoreWire(t, 1, 1);
+
+ new CoreOrGate(t, 1, t2.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd());
+ new CoreOrGate(t, 1, t1.createReadWriteEnd(), s.createReadOnlyEnd(), q.createReadOnlyEnd());
+ new CoreNotGate(t, 1, t2.createReadOnlyEnd(), q.createReadWriteEnd());
+ new CoreNotGate(t, 1, t1.createReadOnlyEnd(), nq.createReadWriteEnd());
+
+ ReadWriteEnd sIn = s.createReadWriteEnd(), rIn = r.createReadWriteEnd();
+
+ sIn.feedSignals(Bit.ONE);
+ rIn.feedSignals(Bit.ZERO);
+
+ t.executeAll();
+
+ assertEquals(Bit.ONE, q.getValue());
+ assertEquals(Bit.ZERO, nq.getValue());
+
+ sIn.feedSignals(Bit.ZERO);
+
+ t.executeAll();
+ assertEquals(Bit.ONE, q.getValue());
+ assertEquals(Bit.ZERO, nq.getValue());
+
+ rIn.feedSignals(Bit.ONE);
+
+ t.executeAll();
+
+ assertEquals(Bit.ZERO, q.getValue());
+ assertEquals(Bit.ONE, nq.getValue());
+ }
+
+ @Test
+ void numericValueTest()
+ {
+ CoreWire a = new CoreWire(t, 4, 1);
+ a.createReadWriteEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE);
+
+ t.executeAll();
+
+ assertEquals(15, a.getUnsignedValue());
+ assertEquals(-1, a.getSignedValue());
+ }
+
+ boolean flag = false;
+
+ @Test
+ void simpleTimelineTest()
+ {
+ Timeline t = new Timeline(3);
+ flag = false;
+ t.addEvent((e) ->
+ {
+ if (!flag)
+ fail("Events executed out of order!");
+ flag = false;
+ }, 15);
+ t.addEvent((e) ->
+ {
+ if (flag)
+ fail("Events executed out of order!");
+ flag = true;
+ }, 10);
+ t.addEvent((e) ->
+ {
+ if (flag)
+ fail("Events executed out of order!");
+ flag = true;
+ }, 20);
+ t.addEvent((e) ->
+ {
+ fail("Only supposed to execute until timestamp 20, not 25");
+ }, 25);
+
+ t.executeUntil(t.laterThan(20), 100);
+
+ if (!flag)
+ fail("Not all events were executed in order!");
+ }
+
+ // TODO: Adapt this test, now that update notifications are issued whenever any input to a wire changes
+ @Disabled("Out of date")
+ @Test
+ void multipleInputs()
+ {
+ CoreWire w = new CoreWire(t, 2, 1);
+ ReadWriteEnd wI1 = w.createReadWriteEnd(), wI2 = w.createReadWriteEnd();
+ wI1.feedSignals(Bit.ONE, Bit.Z);
+ wI2.feedSignals(Bit.Z, Bit.X);
+ t.executeAll();
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.X);
+
+ wI2.feedSignals(Bit.ZERO, Bit.Z);
+ t.executeAll();
+ assertBitArrayEquals(w.getValues(), Bit.X, Bit.Z);
+
+ wI2.feedSignals(Bit.Z, Bit.Z);
+ t.executeAll();
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
+
+ wI2.feedSignals(Bit.ONE, Bit.Z);
+ ReadEnd rE = w.createReadOnlyEnd();
+ rE.registerObserver((i) -> fail("WireEnd notified observer, although value did not change."));
+ t.executeAll();
+ rE.close();
+ wI1.feedSignals(Bit.X, Bit.X);
+ t.executeAll();
+ wI1.registerObserver((i) -> fail("WireEnd notified observer, although it was closed."));
+ wI1.close();
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
+ }
+
+ private static void assertBitArrayEquals(BitVector actual, Bit... expected)
+ {
+ assertArrayEquals(expected, actual.getBits());
+ }
+}
import javax.swing.JPanel;
import javax.swing.WindowConstants;
-import net.mograsim.logic.core.components.ManualSwitch;
-import net.mograsim.logic.core.components.gates.NotGate;
-import net.mograsim.logic.core.components.gates.OrGate;
+import net.mograsim.logic.core.components.CoreManualSwitch;
+import net.mograsim.logic.core.components.gates.CoreNotGate;
+import net.mograsim.logic.core.components.gates.CoreOrGate;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.timeline.Timeline.ExecutionResult;
-import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.CoreWire;
public class GUITest extends JPanel
{
private Timeline t = new Timeline(11);
- Wire r = new Wire(t, 1, WIRE_DELAY);
- Wire s = new Wire(t, 1, WIRE_DELAY);
- Wire t1 = new Wire(t, 1, WIRE_DELAY);
- Wire t2 = new Wire(t, 1, WIRE_DELAY);
- Wire q = new Wire(t, 1, WIRE_DELAY);
- Wire nq = new Wire(t, 1, WIRE_DELAY);
+ CoreWire r = new CoreWire(t, 1, WIRE_DELAY);
+ CoreWire s = new CoreWire(t, 1, WIRE_DELAY);
+ CoreWire t1 = new CoreWire(t, 1, WIRE_DELAY);
+ CoreWire t2 = new CoreWire(t, 1, WIRE_DELAY);
+ CoreWire q = new CoreWire(t, 1, WIRE_DELAY);
+ CoreWire nq = new CoreWire(t, 1, WIRE_DELAY);
- ManualSwitch rIn = new ManualSwitch(t, r.createReadWriteEnd());
- ManualSwitch sIn = new ManualSwitch(t, s.createReadWriteEnd());
+ CoreManualSwitch rIn = new CoreManualSwitch(t, r.createReadWriteEnd());
+ CoreManualSwitch sIn = new CoreManualSwitch(t, s.createReadWriteEnd());
- OrGate or1 = new OrGate(t, OR_DELAY, t2.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd());
- OrGate or2 = new OrGate(t, OR_DELAY, t1.createReadWriteEnd(), s.createReadOnlyEnd(), q.createReadOnlyEnd());
- NotGate not1 = new NotGate(t, NOT_DELAY, t2.createReadOnlyEnd(), q.createReadWriteEnd());
- NotGate not2 = new NotGate(t, NOT_DELAY, t1.createReadOnlyEnd(), nq.createReadWriteEnd());
+ CoreOrGate or1 = new CoreOrGate(t, OR_DELAY, t2.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd());
+ CoreOrGate or2 = new CoreOrGate(t, OR_DELAY, t1.createReadWriteEnd(), s.createReadOnlyEnd(), q.createReadOnlyEnd());
+ CoreNotGate not1 = new CoreNotGate(t, NOT_DELAY, t2.createReadOnlyEnd(), q.createReadWriteEnd());
+ CoreNotGate not2 = new CoreNotGate(t, NOT_DELAY, t1.createReadOnlyEnd(), nq.createReadWriteEnd());
- Map<ManualSwitch, Rectangle> switchMap = new HashMap<>();
+ Map<CoreManualSwitch, Rectangle> switchMap = new HashMap<>();
int height;
int width;
@Override
public void mouseReleased(MouseEvent e)
{
- for (Entry<ManualSwitch, Rectangle> dim : switchMap.entrySet())
+ for (Entry<CoreManualSwitch, Rectangle> dim : switchMap.entrySet())
{
if (dim.getValue().contains(e.getPoint()))
{
@Override
public void mousePressed(MouseEvent e)
{
- for (Entry<ManualSwitch, Rectangle> dim : switchMap.entrySet())
+ for (Entry<CoreManualSwitch, Rectangle> dim : switchMap.entrySet())
{
if (dim.getValue().contains(e.getPoint()))
{
g.drawString(s, x - (int) (w * anchorX), y + (int) (h * anchorY));
}
- private void drawWire(Graphics g, Wire wa, String name, double x1, double y1, double x2, double y2)
+ private void drawWire(Graphics g, CoreWire wa, String name, double x1, double y1, double x2, double y2)
{
setTo(g, wa);
g.drawLine(gX(x1), gY(y1), gX(x2), gY(y2));
}
- private void drawSwitch(Graphics g, ManualSwitch ms, String text, double posX1, double posY1, double posX2, double posY2)
+ private void drawSwitch(Graphics g, CoreManualSwitch ms, String text, double posX1, double posY1, double posX2, double posY2)
{
int x1 = gX(posX1) - 5;
int x2 = gX(posX2) + 5;
g.setColor(Color.BLACK);
}
- private static void setTo(Graphics g, Wire wa)
+ private static void setTo(Graphics g, CoreWire wa)
{
switch (wa.getValue())
{
+++ /dev/null
-package net.mograsim.logic.core.tests;
-
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-
-import java.util.function.LongConsumer;
-
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-
-public final class TestBitDisplay extends BitDisplay
-{
-
- public TestBitDisplay(Timeline timeline, ReadEnd in)
- {
- super(timeline, in);
- }
-
- public void assertDisplays(Bit... expected)
- {
- assertArrayEquals(expected, getDisplayedValue().getBits());
- }
-
- public void assertAfterSimulationIs(Bit... expected)
- {
- timeline.executeAll();
- assertDisplays(expected);
- }
-
- public void assertAfterSimulationIs(LongConsumer r, Bit... expected)
- {
- while (timeline.hasNext())
- {
- timeline.executeNext();
- r.accept(timeline.getSimulationTime());
- }
- assertDisplays(expected);
- }
-
- @Override
- protected void compute()
- {
- super.compute();
- System.out.println("update: value is " + getDisplayedValue());
- }
-}
--- /dev/null
+package net.mograsim.logic.core.tests;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import java.util.function.LongConsumer;
+
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.timeline.Timeline;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+
+public final class TestCoreBitDisplay extends CoreBitDisplay
+{
+
+ public TestCoreBitDisplay(Timeline timeline, ReadEnd in)
+ {
+ super(timeline, in);
+ }
+
+ public void assertDisplays(Bit... expected)
+ {
+ assertArrayEquals(expected, getDisplayedValue().getBits());
+ }
+
+ public void assertAfterSimulationIs(Bit... expected)
+ {
+ timeline.executeAll();
+ assertDisplays(expected);
+ }
+
+ public void assertAfterSimulationIs(LongConsumer r, Bit... expected)
+ {
+ while (timeline.hasNext())
+ {
+ timeline.executeNext();
+ r.accept(timeline.getSimulationTime());
+ }
+ assertDisplays(expected);
+ }
+
+ @Override
+ protected void compute()
+ {
+ super.compute();
+ System.out.println("update: value is " + getDisplayedValue());
+ }
+}
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import java.util.Map;
import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import java.util.Map;
import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import java.util.Map;
import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
package net.mograsim.logic.model.am2900.machine;
-import net.mograsim.logic.core.components.Clock;
+import net.mograsim.logic.core.components.CoreClock;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.ViewModel;
private Am2900MachineDefinition machineDefinition;
private ViewModelModifiable viewModel;
private Timeline timeline;
- private Clock clock;
+ private CoreClock clock;
public Am2900Machine(Am2900MachineDefinition am2900MachineDefinition)
{
}
@Override
- public Clock getClock()
+ public CoreClock getClock()
{
return clock;
}
package net.mograsim.logic.model.am2900.am2901;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.am2900.util.SwitchWithDisplay;
public class TestableAm2901Impl implements TestableAm2901
{
private GUIComponent am2901;
- private ManualSwitch I8, I7, I6, I5, I4, I3, I2, I1, I0;
- private ManualSwitch C;
- private ManualSwitch Cn;
- private ManualSwitch D1, D2, D3, D4;
- private ManualSwitch A0, A1, A2, A3;
- private ManualSwitch B0, B1, B2, B3;
- private BitDisplay Y1, Y2, Y3, Y4;
- private BitDisplay F_0, Cn_4, OVR, F3;
+ private CoreManualSwitch I8, I7, I6, I5, I4, I3, I2, I1, I0;
+ private CoreManualSwitch C;
+ private CoreManualSwitch Cn;
+ private CoreManualSwitch D1, D2, D3, D4;
+ private CoreManualSwitch A0, A1, A2, A3;
+ private CoreManualSwitch B0, B1, B2, B3;
+ private CoreBitDisplay Y1, Y2, Y3, Y4;
+ private CoreBitDisplay F_0, Cn_4, OVR, F3;
private SwitchWithDisplay RAMn, RAMn_3, Qn, Qn_3;
private final TestEnvironmentHelper testHelper = new TestEnvironmentHelper(this, "GUIAm2901");
package net.mograsim.logic.model.am2900.am2904;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.am2900.util.SwitchWithDisplay;
{
private GUIComponent am2904;
- private ManualSwitch I;
- private ManualSwitch C;
- private ManualSwitch Cx;
- private ManualSwitch IC, IN, IOVR, IZ;
- private ManualSwitch _CEM, _CEmu;
- private ManualSwitch _EC, _EN, _EOVR, _EZ;
- private ManualSwitch _OECT, _OEY;
- private ManualSwitch _SE;
- private BitDisplay C0;
- private BitDisplay CT;
+ private CoreManualSwitch I;
+ private CoreManualSwitch C;
+ private CoreManualSwitch Cx;
+ private CoreManualSwitch IC, IN, IOVR, IZ;
+ private CoreManualSwitch _CEM, _CEmu;
+ private CoreManualSwitch _EC, _EN, _EOVR, _EZ;
+ private CoreManualSwitch _OECT, _OEY;
+ private CoreManualSwitch _SE;
+ private CoreBitDisplay C0;
+ private CoreBitDisplay CT;
private SwitchWithDisplay SIO0, SIOn, QIO0, QIOn;
private SwitchWithDisplay YC, YN, YOVR, YZ;
package net.mograsim.logic.model.am2900.am2910;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.am2900.util.TestEnvironmentHelper;
import net.mograsim.logic.model.am2900.util.TestEnvironmentHelper.DebugState;
{
private GUIComponent am2901;
- private ManualSwitch I;
- private ManualSwitch C;
- private ManualSwitch CI;
- private ManualSwitch D;
- private ManualSwitch _CC;
- private ManualSwitch _CCEN;
- private ManualSwitch _RLD;
- private ManualSwitch _OE;
- private BitDisplay _FULL;
- private BitDisplay Y;
- private BitDisplay _PL, _MAP, _VECT;
+ private CoreManualSwitch I;
+ private CoreManualSwitch C;
+ private CoreManualSwitch CI;
+ private CoreManualSwitch D;
+ private CoreManualSwitch _CC;
+ private CoreManualSwitch _CCEN;
+ private CoreManualSwitch _RLD;
+ private CoreManualSwitch _OE;
+ private CoreBitDisplay _FULL;
+ private CoreBitDisplay Y;
+ private CoreBitDisplay _PL, _MAP, _VECT;
private final TestEnvironmentHelper testHelper = new TestEnvironmentHelper(this, "GUIAm2910");
package net.mograsim.logic.model.am2900.util;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.atomic.GUIBitDisplay;
return pin;
}
- public final BitDisplay getBitDisplay()
+ public final CoreBitDisplay getBitDisplay()
{
return guiBitDisplay.getBitDisplay();
}
- public final ManualSwitch getManualSwitch()
+ public final CoreManualSwitch getManualSwitch()
{
return guiManualSwitch.getManualSwitch();
}
import java.util.Set;
import java.util.TreeSet;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreBitDisplay;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.model.LogicUIStandaloneGUI;
import net.mograsim.logic.model.am2900.Am2900Loader;
{
Field f = testEnvClass.getDeclaredField(javaIdentId);
Class<?> type = f.getType();
- if (ManualSwitch.class.isAssignableFrom(type))
+ if (CoreManualSwitch.class.isAssignableFrom(type))
{
GUIManualSwitch gms = new GUIManualSwitch(viewModel, p.logicWidth);
modellingTool.connect(p, gms.getOutputPin());
idSwitchMap.put(p.name, gms);
- } else if (BitDisplay.class.isAssignableFrom(type))
+ } else if (CoreBitDisplay.class.isAssignableFrom(type))
{
GUIBitDisplay gbd = new GUIBitDisplay(viewModel, p.logicWidth);
modellingTool.connect(p, gbd.getInputPin());
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.CoreWire;
import net.mograsim.logic.model.model.wires.GUIWire;
public class WirePointHandle extends Handle
}
/**
- * Sets the index of the {@link Point} within the parent {@link Wire}s path that is controlled by this handle
+ * Sets the index of the {@link Point} within the parent {@link CoreWire}s path that is controlled by this handle
*
* @param index Index of the Point in the Wires path.
* @throws IndexOutOfBoundsException
package net.mograsim.logic.model.model.components.atomic;
-import net.mograsim.logic.core.components.gates.AndGate;
+import net.mograsim.logic.core.components.gates.CoreAndGate;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.model.modeladapter.componentadapters.SimpleGateAdapter;
static
{
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIAndGate.class, AndGate::new));
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIAndGate.class, CoreAndGate::new));
IndirectGUIComponentCreator.setComponentSupplier(GUIAndGate.class.getCanonicalName(),
(m, p, n) -> new GUIAndGate(m, p.getAsInt(), n));
}
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.components.BitDisplay;
+import net.mograsim.logic.core.components.CoreBitDisplay;
import net.mograsim.logic.core.types.BitVectorFormatter;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
private final Pin inputPin;
private final LogicObserver logicObs;
- private BitDisplay bitDisplay;
+ private CoreBitDisplay bitDisplay;
public GUIBitDisplay(ViewModelModifiable model, int logicWidth)
{
gc.setFont(oldFont);
}
- public void setLogicModelBinding(BitDisplay bitDisplay)
+ public void setLogicModelBinding(CoreBitDisplay bitDisplay)
{
if (this.bitDisplay != null)
this.bitDisplay.deregisterObserver(logicObs);
return bitDisplay != null;
}
- public BitDisplay getBitDisplay()
+ public CoreBitDisplay getBitDisplay()
{
return bitDisplay;
}
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.components.Clock;
+import net.mograsim.logic.core.components.CoreClock;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.components.Orientation;
private final LogicObserver logicObs;
private GUIClockParams params;
private OrientationCalculator oc;
- private Clock clock;
+ private CoreClock clock;
public GUIClock(ViewModelModifiable model, GUIClockParams params)
{
gc.setFont(oldFont);
}
- public void setLogicModelBinding(Clock clock)
+ public void setLogicModelBinding(CoreClock clock)
{
if (this.clock != null)
this.clock.deregisterObserver(logicObs);
}
}
- public Clock getClock()
+ public CoreClock getClock()
{
return clock;
}
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.core.types.BitVectorFormatter;
private final Pin outputPin;
private final LogicObserver logicObs;
- private ManualSwitch logicSwitch;
+ private CoreManualSwitch logicSwitch;
public GUIManualSwitch(ViewModelModifiable model, int logicWidth)
{
}
}
- public void setLogicModelBinding(ManualSwitch logicSwitch)
+ public void setLogicModelBinding(CoreManualSwitch logicSwitch)
{
if (this.logicSwitch != null)
this.logicSwitch.deregisterObserver(logicObs);
return true;
}
- public ManualSwitch getManualSwitch()
+ public CoreManualSwitch getManualSwitch()
{
return logicSwitch;
}
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
package net.mograsim.logic.model.model.components.atomic;
-import net.mograsim.logic.core.components.gates.NandGate;
+import net.mograsim.logic.core.components.gates.CoreNandGate;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.model.modeladapter.componentadapters.SimpleGateAdapter;
static
{
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINandGate.class, NandGate::new));
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINandGate.class, CoreNandGate::new));
IndirectGUIComponentCreator.setComponentSupplier(GUINandGate.class.getCanonicalName(),
(m, p, n) -> new GUINandGate(m, p.getAsInt(), n));
}
package net.mograsim.logic.model.model.components.atomic;
-import net.mograsim.logic.core.components.gates.NotGate;
+import net.mograsim.logic.core.components.gates.CoreNotGate;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.model.modeladapter.componentadapters.SimpleGateAdapter;
static
{
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new NotGate(t, p, i[0], o)));
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new CoreNotGate(t, p, i[0], o)));
IndirectGUIComponentCreator.setComponentSupplier(GUINotGate.class.getCanonicalName(),
(m, p, n) -> new GUINotGate(m, p.getAsInt(), n));
}
package net.mograsim.logic.model.model.components.atomic;
-import net.mograsim.logic.core.components.gates.OrGate;
+import net.mograsim.logic.core.components.gates.CoreOrGate;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.model.modeladapter.componentadapters.SimpleGateAdapter;
static
{
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIOrGate.class, OrGate::new));
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIOrGate.class, CoreOrGate::new));
IndirectGUIComponentCreator.setComponentSupplier(GUIOrGate.class.getCanonicalName(),
(m, p, n) -> new GUIOrGate(m, p.getAsInt(), n));
}
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.core.LogicObserver;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.preferences.ColorDefinition;
import net.mograsim.preferences.ColorManager;
}
/**
- * If this {@link GUIWire} has a logic model binding, delegates to {@link Wire#forceValues(BitVector)} for the {@link Wire}
+ * If this {@link GUIWire} has a logic model binding, delegates to {@link CoreWire#forceValues(BitVector)} for the {@link CoreWire}
* corresponding to this {@link GUIWire}.
*
* @author Daniel Kirschten
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.LogicObserver;
import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.ViewModelModifiable;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.serializing.IdentifyParams;
import java.util.stream.Collectors;
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.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.ViewModel;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
return timeline;
}
- private static void convert(ViewModel viewModel, LogicModelParameters params, Timeline timeline, Map<Pin, Wire> externalWires)
+ private static void convert(ViewModel viewModel, LogicModelParameters params, Timeline timeline, Map<Pin, CoreWire> externalWires)
{
- Map<Pin, Wire> logicWiresPerPin = convertWires(getAllPins(viewModel), viewModel.getWiresByName().values(), externalWires, params,
+ Map<Pin, CoreWire> logicWiresPerPin = convertWires(getAllPins(viewModel), viewModel.getWiresByName().values(), externalWires, params,
timeline);
- Map<Pin, Wire> logicWiresPerPinUnmodifiable = Collections.unmodifiableMap(logicWiresPerPin);
+ Map<Pin, CoreWire> logicWiresPerPinUnmodifiable = Collections.unmodifiableMap(logicWiresPerPin);
for (GUIComponent guiComp : viewModel.getComponentsByName().values())
{
{
SubmodelComponent guiCompCasted = (SubmodelComponent) guiComp;
Map<String, Pin> supermodelPins = guiCompCasted.getSupermodelPins();
- Map<Pin, Wire> externalWiresForSubmodel = supermodelPins.entrySet().stream()
+ Map<Pin, CoreWire> externalWiresForSubmodel = supermodelPins.entrySet().stream()
.collect(Collectors.toMap(e -> guiCompCasted.getSubmodelPin(e.getKey()), e -> logicWiresPerPin.get(e.getValue())));
convert(guiCompCasted.submodel, params, timeline, externalWiresForSubmodel);
} else if (guiComp instanceof WireCrossPoint)
.collect(Collectors.toSet());
}
- private static Map<Pin, Wire> convertWires(Set<Pin> allPins, Collection<GUIWire> wires, Map<Pin, Wire> externalWires,
+ private static Map<Pin, CoreWire> convertWires(Set<Pin> allPins, Collection<GUIWire> wires, Map<Pin, CoreWire> externalWires,
LogicModelParameters params, Timeline timeline)
{
Map<Pin, Set<Pin>> connectedPinGroups = getConnectedPinGroups(allPins, wires);
- Map<Pin, Wire> logicWiresPerPin = createLogicWires(params, timeline, connectedPinGroups, externalWires);
+ Map<Pin, CoreWire> logicWiresPerPin = createLogicWires(params, timeline, connectedPinGroups, externalWires);
setGUIWiresLogicModelBinding(wires, logicWiresPerPin);
return logicWiresPerPin;
}
- private static Map<Pin, Wire> createLogicWires(LogicModelParameters params, Timeline timeline, Map<Pin, Set<Pin>> connectedPinGroups,
- Map<Pin, Wire> externalWires)
+ private static Map<Pin, CoreWire> createLogicWires(LogicModelParameters params, Timeline timeline, Map<Pin, Set<Pin>> connectedPinGroups,
+ Map<Pin, CoreWire> externalWires)
{
- Map<Pin, Wire> logicWiresPerPin = new HashMap<>();
- Map<Set<Pin>, Wire> logicWiresPerPinGroup = new HashMap<>();
+ Map<Pin, CoreWire> logicWiresPerPin = new HashMap<>();
+ Map<Set<Pin>, CoreWire> logicWiresPerPinGroup = new HashMap<>();
for (Entry<Pin, Set<Pin>> e : connectedPinGroups.entrySet())
logicWiresPerPin.put(e.getKey(), logicWiresPerPinGroup.computeIfAbsent(e.getValue(), set ->
{
- Wire externalWire = null;
+ CoreWire externalWire = null;
for (Pin p : set)
{
- Wire externalWireCandidate = externalWires.get(p);
+ CoreWire externalWireCandidate = externalWires.get(p);
if (externalWireCandidate != null)
if (externalWire == null)
externalWire = externalWireCandidate;
else if (externalWire.width == externalWireCandidate.width)
- Wire.fuse(externalWire, externalWireCandidate);
+ CoreWire.fuse(externalWire, externalWireCandidate);
else
throw new IllegalArgumentException(
"Two pins to external wires with different logicWidths can't be connected directly");
}
- return externalWire == null ? new Wire(timeline, e.getKey().logicWidth, params.wireTravelTime) : externalWire;
+ return externalWire == null ? new CoreWire(timeline, e.getKey().logicWidth, params.wireTravelTime) : externalWire;
}));
return logicWiresPerPin;
}
- private static void setGUIWiresLogicModelBinding(Collection<GUIWire> wires, Map<Pin, Wire> logicWiresPerPin)
+ private static void setGUIWiresLogicModelBinding(Collection<GUIWire> wires, Map<Pin, CoreWire> logicWiresPerPin)
{
- Map<Wire, ReadEnd> guiWireSharedReadEnd = logicWiresPerPin.values().stream().distinct()
- .collect(Collectors.toMap(Function.identity(), Wire::createReadOnlyEnd));
+ Map<CoreWire, ReadEnd> guiWireSharedReadEnd = logicWiresPerPin.values().stream().distinct()
+ .collect(Collectors.toMap(Function.identity(), CoreWire::createReadOnlyEnd));
for (GUIWire guiWire : wires)
guiWire.setLogicModelBinding(guiWireSharedReadEnd.get(logicWiresPerPin.get(guiWire.getPin1())));
}
@SuppressWarnings("unchecked")
private static <G extends GUIComponent> void createAndLinkComponent(Timeline timeline, LogicModelParameters params,
- GUIComponent guiComponent, Map<Pin, Wire> logicWiresPerPin)
+ GUIComponent guiComponent, Map<Pin, CoreWire> logicWiresPerPin)
{
Class<?> cls = guiComponent.getClass();
ComponentAdapter<? super G> adapter = null;
import java.util.Map;
-import net.mograsim.logic.core.components.BitDisplay;
+import net.mograsim.logic.core.components.CoreBitDisplay;
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.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.components.atomic.GUIBitDisplay;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIBitDisplay guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
ReadEnd end = logicWiresPerPin.get(guiComponent.getInputPin()).createReadOnlyEnd();
- BitDisplay bitDisplay = new BitDisplay(timeline, end);
+ CoreBitDisplay bitDisplay = new CoreBitDisplay(timeline, end);
guiComponent.setLogicModelBinding(bitDisplay);
}
}
\ No newline at end of file
import java.util.Map;
-import net.mograsim.logic.core.components.Clock;
+import net.mograsim.logic.core.components.CoreClock;
import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.components.atomic.GUIClock;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
}
@Override
- public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIClock guiClock, Map<Pin, Wire> logicWiresPerPin)
+ public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIClock guiClock, Map<Pin, CoreWire> logicWiresPerPin)
{
ReadWriteEnd out = logicWiresPerPin.get(guiClock.getOutputPin()).createReadWriteEnd();
- Clock c = new Clock(timeline, out, guiClock.getDelta());
+ CoreClock c = new CoreClock(timeline, out, guiClock.getDelta());
guiClock.setLogicModelBinding(c);
}
import java.util.Map;
import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.CoreWire;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
{
public Class<G> getSupportedClass();
- public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent, Map<Pin, Wire> logicWiresPerPin);
+ public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent, Map<Pin, CoreWire> logicWiresPerPin);
}
\ No newline at end of file
import java.util.Map;
import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.CoreWire;
import net.mograsim.logic.model.model.components.atomic.GUIFixedOutput;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIFixedOutput guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
logicWiresPerPin.get(guiComponent.getPin("out")).createReadWriteEnd().feedSignals(guiComponent.bits);
}
import java.util.Map;
-import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.components.CoreManualSwitch;
import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.components.atomic.GUIManualSwitch;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIManualSwitch guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
ReadWriteEnd end = logicWiresPerPin.get(guiComponent.getOutputPin()).createReadWriteEnd();
- ManualSwitch manualSwitch = new ManualSwitch(timeline, end);
+ CoreManualSwitch manualSwitch = new CoreManualSwitch(timeline, end);
guiComponent.setLogicModelBinding(manualSwitch);
}
}
\ No newline at end of file
import java.util.Map;
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.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.components.atomic.GUIMerger;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIMerger guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
- Wire output = logicWiresPerPin.get(guiComponent.getPin("O"));
+ CoreWire output = logicWiresPerPin.get(guiComponent.getPin("O"));
ReadEnd[] inputEnds = new ReadEnd[guiComponent.logicWidth];
for (int i = 0; i < guiComponent.logicWidth; i++)
{
- Wire input = logicWiresPerPin.get(guiComponent.getPin("I" + (guiComponent.logicWidth - 1 - i)));
- Wire.fuse(input, output, 0, i);
+ CoreWire input = logicWiresPerPin.get(guiComponent.getPin("I" + (guiComponent.logicWidth - 1 - i)));
+ CoreWire.fuse(input, output, 0, i);
inputEnds[i] = input.createReadOnlyEnd();
}
guiComponent.setLogicModelBinding(inputEnds, output.createReadOnlyEnd());
import java.util.Map;
import net.mograsim.logic.core.timeline.Timeline;
-import net.mograsim.logic.core.wires.Wire;
+import net.mograsim.logic.core.wires.CoreWire;
import net.mograsim.logic.model.model.components.GUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
}
@Override
- public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, T guiComponent, Map<Pin, Wire> logicWiresPerPin)
+ public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, T guiComponent, Map<Pin, CoreWire> logicWiresPerPin)
{
// do nothing
}
import java.util.Map;
-import net.mograsim.logic.core.components.Component;
+import net.mograsim.logic.core.components.CoreComponent;
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;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularGUIGate;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
}
@Override
- public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent, Map<Pin, Wire> logicWiresPerPin)
+ public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, G guiComponent, Map<Pin, CoreWire> logicWiresPerPin)
{
ReadWriteEnd out = logicWiresPerPin.get(guiComponent.getPin("Y")).createReadWriteEnd();
public static interface ComponentConstructor
{
- public Component newComponent(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd[] ins);
+ public CoreComponent newComponent(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd[] ins);
}
}
\ No newline at end of file
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;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.model.wires.PinUsage;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, SimpleRectangularHardcodedGUIComponent guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
Map<String, ReadEnd> readEnds = new HashMap<>();
Map<String, ReadWriteEnd> readWriteEnds = new HashMap<>();
for (Pin pin : guiComponent.getPins().values())
{
- Wire wire = logicWiresPerPin.get(pin);
+ CoreWire wire = logicWiresPerPin.get(pin);
ReadEnd end;
if (pin.usage != PinUsage.INPUT)
{
import java.util.Map;
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.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
import net.mograsim.logic.model.model.components.atomic.GUISplitter;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUISplitter guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
- Wire input = logicWiresPerPin.get(guiComponent.getPin("I"));
+ CoreWire input = logicWiresPerPin.get(guiComponent.getPin("I"));
ReadEnd[] outputEnds = new ReadEnd[guiComponent.logicWidth];
for (int i = 0; i < guiComponent.logicWidth; i++)
{
- Wire output = logicWiresPerPin.get(guiComponent.getPin("O" + (guiComponent.logicWidth - 1 - i)));
- Wire.fuse(input, output, i, 0);
+ CoreWire output = logicWiresPerPin.get(guiComponent.getPin("O" + (guiComponent.logicWidth - 1 - i)));
+ CoreWire.fuse(input, output, i, 0);
outputEnds[i] = output.createReadOnlyEnd();
}
guiComponent.setLogicModelBinding(input.createReadOnlyEnd(), outputEnds);
import java.util.Map;
-import net.mograsim.logic.core.components.TriStateBuffer;
+import net.mograsim.logic.core.components.CoreTriStateBuffer;
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;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.components.atomic.GUITriStateBuffer;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
@SuppressWarnings("unused")
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUITriStateBuffer guiTsb,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
ReadEnd in = logicWiresPerPin.get(guiTsb.getPin("IN")).createReadOnlyEnd();
ReadEnd enable = logicWiresPerPin.get(guiTsb.getPin("EN")).createReadOnlyEnd();
ReadWriteEnd out = logicWiresPerPin.get(guiTsb.getPin("OUT")).createReadWriteEnd();
- new TriStateBuffer(timeline, params.gateProcessTime, in, out, enable);
+ new CoreTriStateBuffer(timeline, params.gateProcessTime, in, out, enable);
}
}
package net.mograsim.machine;
-import net.mograsim.logic.core.components.Clock;
+import net.mograsim.logic.core.components.CoreClock;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.ViewModel;
ViewModel getModel();
- Clock getClock();
+ CoreClock getClock();
BitVector getRegister(Register r);
import java.util.Map;
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;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.modeladapter.LogicModelParameters;
import net.mograsim.logic.model.modeladapter.componentadapters.ComponentAdapter;
@SuppressWarnings("unused")
@Override
public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIMemoryWA guiComponent,
- Map<Pin, Wire> logicWiresPerPin)
+ Map<Pin, CoreWire> logicWiresPerPin)
{
ReadWriteEnd data = logicWiresPerPin.get(guiComponent.getDataPin()).createReadWriteEnd();
ReadEnd address = logicWiresPerPin.get(guiComponent.getAddressPin()).createReadOnlyEnd();
import java.util.List;
-import net.mograsim.logic.core.components.BasicComponent;
+import net.mograsim.logic.core.components.BasicCoreComponent;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadEnd;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.machine.MainMemoryDefinition;
/**
* A memory component that only allows access to words of a specific width
*/
-public class WordAddressableMemoryComponent extends BasicComponent
+public class WordAddressableMemoryComponent extends BasicCoreComponent
{
private final WordAddressableMemory memory;
private final static Bit read = Bit.ONE;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
-import net.mograsim.logic.core.wires.Wire;
-import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
+import net.mograsim.logic.core.wires.CoreWire;
+import net.mograsim.logic.core.wires.CoreWire.ReadWriteEnd;
import net.mograsim.machine.MainMemoryDefinition;
class WordAddressableMemoryTest {
@Test
public void wordAddressableMemoryLargeTest()
{
- Wire rW = new Wire(t, 1, 2);
- Wire data = new Wire(t, 16, 2);
- Wire address = new Wire(t, 64, 2);
+ CoreWire rW = new CoreWire(t, 1, 2);
+ CoreWire data = new CoreWire(t, 16, 2);
+ CoreWire address = new CoreWire(t, 64, 2);
ReadWriteEnd rWI = rW.createReadWriteEnd();
ReadWriteEnd dataI = data.createReadWriteEnd();
ReadWriteEnd addressI = address.createReadWriteEnd();