X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.core%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fcore%2Ftypes%2FBitVector.java;h=134669494852256df8868924a63aa687e8b1fb00;hb=8bed58cd47f4e53a0a83e066d38864aa6875502f;hp=4d5365a0188a95961a37e867b36046cfaf165ae9;hpb=bec6c3a711448475c7b8e43dd031efe7b89aba24;p=Mograsim.git diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/types/BitVector.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/types/BitVector.java index 4d5365a0..13466949 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/types/BitVector.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/types/BitVector.java @@ -2,6 +2,7 @@ package net.mograsim.logic.core.types; import static java.lang.String.format; +import java.math.BigInteger; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; @@ -13,17 +14,30 @@ import java.util.function.UnaryOperator; /** * Immutable class representing a {@link Bit}Vector * - * * @author Christian Femers * */ public final class BitVector implements StrictLogicType, Iterable, RandomAccess { + public static final BitVector SINGLE_U = new BitVector(Bit.U); + public static final BitVector SINGLE_X = new BitVector(Bit.X); + public static final BitVector SINGLE_0 = new BitVector(Bit.ZERO); + public static final BitVector SINGLE_1 = new BitVector(Bit.ONE); + public static final BitVector SINGLE_Z = new BitVector(Bit.Z); + + private static final BitVector[] SINGLE_BIT_MAPPING = { SINGLE_U, SINGLE_X, SINGLE_0, SINGLE_1, SINGLE_Z }; + private final Bit[] bits; + private BitVector(Bit single) + { + Objects.requireNonNull(single); + bits = new Bit[] { single }; + } + private BitVector(Bit[] bits) { - this.bits = Objects.requireNonNull(bits);// do this first to "catch" bits==null before the foreach loop + this.bits = Objects.requireNonNull(bits); // do this first to "catch" bits==null before the foreach loop for (Bit bit : bits) if (bit == null) throw new NullPointerException(); @@ -31,33 +45,78 @@ public final class BitVector implements StrictLogicType, IterablebitIndex. (leftmost bit of a binary number at the given index) + */ + public Bit getMSBit(int bitIndex) { return bits[bitIndex]; } + /** + * Returns the least significant bit at bitIndex. (rightmost bit of a binary number at the given index) + */ + public Bit getLSBit(int bitIndex) + { + return bits[bits.length - bitIndex - 1]; + } + public Bit[] getBits() { return bits.clone(); } + /** + * Checks if all bits are {@link Bit#isBinary() binary}. + * + * @see Bit#isBinary() + */ + public boolean isBinary() + { + for (int i = 0; i < bits.length; i++) + { + if (!bits[i].isBinary()) + return false; + } + return true; + } + @Override public BitVector join(BitVector t) { checkCompatibility(t); + if (bits.length == 1) + return SINGLE_BIT_MAPPING[bits[0].join(t.bits[0]).ordinal()]; return new BitVector(binOp(bits.clone(), t.bits, Bit::join)); } @@ -65,6 +124,8 @@ public final class BitVector implements StrictLogicType, Iterable, Iterable, Iterable, Iterable + * An empty BitVectorMutator must not be converted to BitVector or used to manipulate single bits until at least one two + * operand logic operation is performed. */ public static BitVectorMutator empty() { return new BitVectorMutator(null); } + /** + * @see #empty() + */ + public boolean isEmpty() + { + return bits == null; + } + /** * Produces the resulting, immutable {@link BitVector}
* @@ -224,18 +302,50 @@ public final class BitVector implements StrictLogicType, IterablebitIndex. (leftmost bit of a binary number at the given index) + */ + public void setMSBit(int bitIndex, Bit bit) { + if (bits == null) + throw new IllegalStateException("cannot set a bit of an empty mutator"); bits[bitIndex] = bit; } - public Bit getBit(int bitIndex) + /** + * Set the least significant bit at bitIndex. (rightmost bit of a binary number at the given index) + */ + public void setLSBit(int bitIndex, Bit bit) { + if (bits == null) + throw new IllegalStateException("cannot set a bit of an empty mutator"); + bits[bits.length - bitIndex - 1] = bit; + } + + /** + * Returns the most significant bit at bitIndex. (leftmost bit of a binary number at the given index) + */ + public Bit getMSBit(int bitIndex) + { + if (bits == null) + throw new IllegalStateException("cannot get a bit of an empty mutator"); return bits[bitIndex]; } + /** + * Returns the least significant bit at bitIndex. (rightmost bit of a binary number at the given index) + */ + public Bit getLSBit(int bitIndex) + { + if (bits == null) + throw new IllegalStateException("cannot get a bit of an empty mutator"); + return bits[bits.length - bitIndex - 1]; + } + public int length() { + if (bits == null) + throw new IllegalStateException("cannot obtain a length of an empty mutator"); return bits.length; } @@ -273,7 +383,7 @@ public final class BitVector implements StrictLogicType, Iterableoffset to the right.
- * Therefore offset + other.length() <= this.length() needs to be true. + * Therefore offset + other.length() <= this.wdith() needs to be true. * * @throws ArrayIndexOutOfBoundsException if offset + other.length() > this.length() * @@ -287,7 +397,7 @@ public final class BitVector implements StrictLogicType, Iterable, Iterable= 0; i--) + { + if (Bit.ONE == bits[bits.length - i - 1]) + { + try + { + bytes[bytes.length - (i / 8) - 1] |= 1 << (i % 8); + } + catch (IndexOutOfBoundsException e) + { + e.printStackTrace(); + } + } + } + return new BigInteger(bytes); + } + + public long getUnsignedValueLong() + { + return getUnsignedValue().longValue(); + } + + /** + * Returns the value of the BitVector as BigInteger interpreted as a two's complement number. + * + * @throws NumberFormatException if the BitVector is not {@link #isBinary() binary}. + * + * @author Daniel Kirschten + */ + public BigInteger getSignedValue() + { + BigInteger unsignedValue = getUnsignedValue(); + if (bits[bits.length - 1] == Bit.ZERO) + return unsignedValue; + return unsignedValue.subtract(BitVector.of(Bit.ONE, bits.length).getUnsignedValue()).subtract(BigInteger.ONE);// TODO speed this up! + } + + public long getSignedValueLong() + { + return getSignedValue().longValue(); + } + + /** + * Parses a String containing solely {@link Bit} symbols (MSB first) * * @see #toString() */ @@ -315,6 +477,23 @@ public final class BitVector implements StrictLogicType, Iterable singleBitOperation) + { + Bit[] newBits = bits.clone(); + newBits[msbIndex] = singleBitOperation.apply(newBits[msbIndex]); + return new BitVector(newBits); + } + + /** + * Iterate over the {@link Bit}s of the BitVector from MSB to LSB (left to right). + */ @Override public Iterator iterator() { @@ -327,7 +506,7 @@ public final class BitVector implements StrictLogicType, Iterable, Iterable