Note: since this change was prolonged for some time, so it needed to be changed in a lot of places. The reason for the renaming is the confusability with the length of a (e.g. physical) wire. But it is more precise to call it (bit-) width, since the length of a BitVector passing through the wire becomes its width. (This seems to be similar named in Verilog)
public Connector(Timeline timeline, ReadWriteEnd a, ReadWriteEnd b)
{
super(timeline);
- if (a.length() != b.length())
- throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length(), b.length()));
+ if (a.width() != b.width())
+ throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.width(), b.width()));
this.a = a;
this.b = b;
a.registerObserver(this);
private int selected = -1;
/**
- * Output {@link Wire}s and in must be of uniform length
+ * Output {@link Wire}s and in must be of uniform width
*
* @param in Must be of uniform length with all outputs.
* @param select Indexes the output array to which the input is mapped. Must have enough bits to index all outputs.
public Demux(Timeline timeline, int processTime, ReadEnd in, ReadEnd select, ReadWriteEnd... outputs)
{
super(timeline, processTime);
- outputSize = in.length();
+ outputSize = in.width();
this.in = in;
this.outputs = outputs;
for (int i = 0; i < this.outputs.length; i++)
{
- if (outputs[i].length() != outputSize)
- throw new IllegalArgumentException("All DEMUX wire arrays must be of uniform length!");
+ 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.length();
+ 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.length() + " select bits (" + maxInputs + ").");
+ + select.width() + " select bits (" + maxInputs + ").");
in.registerObserver(this);
}
public void switchFullOn()
{
- setState(BitVector.of(Bit.ONE, output.length()));
+ setState(BitVector.of(Bit.ONE, output.width()));
}
public void switchFullOff()
{
- setState(BitVector.of(Bit.ZERO, output.length()));
+ setState(BitVector.of(Bit.ZERO, output.width()));
}
public void toggle()
public void setState(BitVector bits)
{
- if (bits.length() != output.length())
+ if (bits.length() != output.width())
throw new IllegalArgumentException("Incorrect bit vector length");
if (bits.equals(output.getInputValues()))
return;
public boolean isFullOn()
{
- return BitVector.of(Bit.ONE, output.length()).equals(output.getInputValues());
+ return BitVector.of(Bit.ONE, output.width()).equals(output.getInputValues());
}
public BitVector getValues()
/**
*
- * @param union The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length().
+ * @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 Merger(Timeline timeline, ReadWriteEnd union, ReadEnd... inputs)
for (int i = 0; i < inputs.length; i++)
{
beginningIndex[i] = length;
- length += inputs[i].length();
+ length += inputs[i].width();
inputs[i].registerObserver(this);
}
- if (length != union.length())
+ if (length != union.width())
throw new IllegalArgumentException(
- "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length().");
+ "The output of merging n WireArrays into one must have width = a1.width() + a2.width() + ... + an.width().");
}
public ReadEnd getInput(int index)
public Mux(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs)
{
super(timeline, processTime);
- outputSize = out.length();
+ outputSize = out.width();
this.inputs = inputs.clone();
for (int i = 0; i < this.inputs.length; i++)
{
- if (inputs[i].length() != outputSize)
- throw new IllegalArgumentException("All MUX wire arrays must be of uniform length!");
+ 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.length();
+ 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.length() + " select bits (" + maxInputs + ").");
+ + select.width() + " select bits (" + maxInputs + ").");
this.out = out;
}
this.input = input;
this.outputs = outputs;
input.registerObserver(this);
- int length = 0;
+ int width = 0;
for (ReadEnd out : outputs)
- length += out.length();
+ width += out.width();
- if (input.length() != length)
+ if (input.width() != width)
throw new IllegalArgumentException(
- "The input of splitting one into n WireArrays must have length = a1.length() + a2.length() + ... + an.length().");
+ "The input of splitting one into n WireArrays must have width = a1.width() + a2.width() + ... + an.width().");
}
protected void compute()
int startIndex = 0;
for (int i = 0; i < outputs.length; i++)
{
- outputs[i].feedSignals(inputBits.subVector(startIndex, startIndex + outputs[i].length()));
- startIndex += outputs[i].length();
+ outputs[i].feedSignals(inputBits.subVector(startIndex, startIndex + outputs[i].width()));
+ startIndex += outputs[i].width();
}
}
public TriStateBuffer(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out, ReadEnd enable)
{
super(timeline, processTime);
- if (in.length() != out.length())
+ if (in.width() != out.width())
throw new IllegalArgumentException(
- "Tri-state output must have the same amount of bits as the input. Input: " + in.length() + " Output: " + out.length());
- if (enable.length() != 1)
- throw new IllegalArgumentException("Tri-state enable must have exactly one bit, not " + enable.length() + ".");
+ "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;
{
protected ReadEnd[] in;
protected ReadWriteEnd out;
- protected final int length;
+ protected final int width;
protected MutationOperation op;
protected boolean invert = false;
{
super(timeline, processTime);
this.op = op;
- length = out.length();
+ 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.length() != length)
+ if (w.width() != width)
throw new IllegalArgumentException("All wires connected to the gate must be of uniform length.");
w.registerObserver(this);
}
private BitVector values;
public final int travelTime;
private List<ReadEnd> attached = new ArrayList<>();
- public final int length;
+ public final int width;
List<ReadWriteEnd> inputs = new ArrayList<>();
Timeline timeline;
- public Wire(Timeline timeline, int length, int travelTime)
+ public Wire(Timeline timeline, int width, int travelTime)
{
- this(timeline, length, travelTime, null);
+ this(timeline, width, travelTime, null);
}
- public Wire(Timeline timeline, int length, int travelTime, String name)
+ public Wire(Timeline timeline, int width, int travelTime, String name)
{
- if (length < 1)
+ if (width < 1)
throw new IllegalArgumentException(
- String.format("Tried to create an array of wires with length %d, but a length of less than 1 makes no sense.", length));
+ 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.length = length;
+ this.width = width;
this.travelTime = travelTime;
initValues();
}
private void initValues()
{
- values = U.toVector(length);
+ values = U.toVector(width);
}
private void setNewValues(BitVector newValues)
{
if (values.equals(newValues))
return;
-// BitVector oldValues = values;
values = newValues;
notifyObservers();
}
void recalculate()
{
- if (inputs.size() == 0)
- setNewValues(BitVector.of(Bit.U, length));
+ if (inputs.isEmpty())
+ setNewValues(U.toVector(width));
else
{
BitVectorMutator mutator = BitVectorMutator.empty();
* 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.
+ * 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()
{
- for (Bit b : values)
- {
- if (b != Bit.ZERO && b != Bit.ONE)
- return false;
- }
- return true;
+ return values.isBinary();
}
/**
public long getSignedValue()
{
long val = getUnsignedValue();
- long mask = 1 << (length - 1);
+ long mask = 1 << (width - 1);
if ((mask & val) != 0)
{
- int shifts = 64 - length;
+ int shifts = 64 - width;
return (val << shifts) >> shifts;
}
return val;
*
* @author Fabian Stemmler
*/
- void attachEnd(ReadEnd end)
+ boolean attachEnd(ReadEnd end)
{
- attached.add(end);
+ return attached.add(end);
}
void detachEnd(ReadEnd end)
private void notifyObservers()
{
- attached.forEach(r -> r.update());
+ attached.forEach(ReadEnd::update);
}
/**
}
/**
- * Included for convenient use on {@link Wire}s of length 1.
+ * Included for convenient use on {@link Wire}s of width 1.
*
* @return The value of bit 0.
*
recalculate();
}
- public int length()
+ public int width()
{
- return length;
+ return width;
}
public Wire getWire()
public class ReadWriteEnd extends ReadEnd
{
- private boolean open, isWriting;
+ private boolean open;
+ private boolean isWriting;
private BitVector inputValues;
ReadWriteEnd()
private void initValues()
{
- inputValues = U.toVector(length);
+ inputValues = U.toVector(width);
}
/**
public void feedSignals(BitVector newValues)
{
- if (newValues.length() != length)
+ if (newValues.length() != width)
throw new IllegalArgumentException(
- String.format("Attempted to input %d bits instead of %d bits.", newValues.length(), length));
+ String.format("Attempted to input %d bits instead of %d bits.", newValues.length(), width));
if (!open)
- throw new RuntimeException("Attempted to write to closed WireArrayEnd.");
+ throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
timeline.addEvent(e -> setValues(newValues), travelTime);
}
public void feedSignals(int startingBit, BitVector bitVector)
{
if (!open)
- throw new RuntimeException("Attempted to write to closed WireArrayEnd.");
+ throw new IllegalStateException("Attempted to write to closed WireArrayEnd.");
timeline.addEvent(e -> setValues(startingBit, bitVector), travelTime);
}
*/
public void clearSignals()
{
- feedSignals(Z.toVector(length));
+ feedSignals(Z.toVector(width));
}
public BitVector wireValuesExcludingMe()
ReadWriteEnd rA = a.createReadWriteEnd(), rB = b.createReadWriteEnd();
rA.setWriting(false);
rB.setWriting(false);
- rA.setValues(BitVector.of(Bit.Z, a.length));
- rB.setValues(BitVector.of(Bit.Z, b.length));
+ rA.setValues(BitVector.of(Bit.Z, a.width));
+ rB.setValues(BitVector.of(Bit.Z, b.width));
Fusion aF = new Fusion(rB, fromA, fromB, length), bF = new Fusion(rA, fromB, fromA, length);
rA.registerObserver(aF);
rB.registerObserver(bF);
*/
public static void fuse(Wire a, Wire b)
{
- fuse(a, b, 0, 0, a.length);
+ fuse(a, b, 0, 0, a.width);
}
private static class Fusion implements LogicObserver
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.length);
- Wire.fuse(b, out, 0, a.length, b.length);
- Wire.fuse(c, out, 0, a.length + b.length, c.length);
+ 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();
break;
case U:
for (ReadWriteEnd e : readWriteEnds.values())
- e.feedSignals(BitVector.of(U, e.length()));
+ e.feedSignals(BitVector.of(U, e.width()));
return null;
case X:
case Z:
for (ReadWriteEnd e : readWriteEnds.values())
- e.feedSignals(BitVector.of(X, e.length()));
+ e.feedSignals(BitVector.of(X, e.width()));
return null;
case ZERO:
break;
if (externalWireCandidate != null)
if (externalWire == null)
externalWire = externalWireCandidate;
- else if (externalWire.length == externalWireCandidate.length)
+ else if (externalWire.width == externalWireCandidate.width)
Wire.fuse(externalWire, externalWireCandidate);
else
throw new IllegalArgumentException(
import net.mograsim.logic.core.components.BasicComponent;
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;
import net.mograsim.machine.MainMemoryDefinition;
ReadEnd rWBit, ReadEnd address)
{
super(timeline, processTime);
- if(data.length() != definition.getCellWidth())
- throw new IllegalArgumentException(String.format("Bit width of data wire does not match main memory definition. Expected: %d Actual: %d", definition.getCellWidth(), data.length()));
- if(rWBit.length() != 1)
- throw new IllegalArgumentException(String.format("Bit width of read/write mode select wire is unexpected. Expected: 1 Actual: %d", rWBit.length()));
- if(address.length() != definition.getMemoryAddressBits())
- throw new IllegalArgumentException(String.format("Bit width of address wire does not match main memory definition. Expected: %d Actual: %d", definition.getMemoryAddressBits(), address.length()));
+ if(data.width() != definition.getCellWidth())
+ throw new IllegalArgumentException(String.format("Bit width of data wire does not match main memory definition. Expected: %d Actual: %d", definition.getCellWidth(), data.width()));
+ if(rWBit.width() != 1)
+ throw new IllegalArgumentException(String.format("Bit width of read/write mode select wire is unexpected. Expected: 1 Actual: %d", rWBit.width()));
+ if(address.width() != definition.getMemoryAddressBits())
+ throw new IllegalArgumentException(String.format("Bit width of address wire does not match main memory definition. Expected: %d Actual: %d", definition.getMemoryAddressBits(), address.width()));
this.data = data;
this.rWBit = rWBit;
this.address = address;
if (!address.hasNumericValue())
{
if (read.equals(rWBit.getValue()))
- data.feedSignals(BitVector.of(Bit.U, data.length()));
+ data.feedSignals(Bit.U.toVector(data.width()));
else
data.clearSignals();
return;