Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.core / src / net / mograsim / logic / core / types / BitVector.java
index aed0288..1346694 100644 (file)
@@ -50,11 +50,11 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                return new BitVector(bits.clone());
        }
 
-       public static BitVector of(Bit bit, int width)
+       public static BitVector of(Bit bit, int length)
        {
-               if (width == 1)
+               if (length == 1)
                        return SINGLE_BIT_MAPPING[bit.ordinal()];
-               return new BitVector(bit.makeArray(width));
+               return new BitVector(bit.makeArray(length));
        }
 
        public static BitVector from(long value, int bits)
@@ -66,9 +66,7 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
        {
                Bit[] values = new Bit[bits];
                for (int i = 0; i < bits; i++)
-               {
                        values[bits - i - 1] = Bit.of(value.testBit(i));
-               }
                return new BitVector(values);
        }
 
@@ -157,21 +155,21 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                return new BitVector(unOp(bits.clone(), Bit::not));
        }
 
-       public int width()
+       public int length()
        {
                return bits.length;
        }
 
        public BitVector concat(BitVector other)
        {
-               Bit[] newBits = Arrays.copyOf(bits, width() + other.width());
-               System.arraycopy(other.bits, 0, newBits, width(), other.width());
+               Bit[] newBits = Arrays.copyOf(bits, length() + other.length());
+               System.arraycopy(other.bits, 0, newBits, length(), other.length());
                return new BitVector(newBits);
        }
 
        public BitVector subVector(int start)
        {
-               return new BitVector(Arrays.copyOfRange(bits, start, width()));
+               return new BitVector(Arrays.copyOfRange(bits, start, length()));
        }
 
        public BitVector subVector(int start, int end)
@@ -181,8 +179,8 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
 
        private void checkCompatibility(BitVector bv)
        {
-               if (width() != bv.width())
-                       throw new IllegalArgumentException(format("BitVector width does not match: %d and %d", width(), bv.width()));
+               if (length() != bv.length())
+                       throw new IllegalArgumentException(format("BitVector length does not match: %d and %d", length(), bv.length()));
        }
 
        static Bit[] binOp(Bit[] dest, Bit[] second, BinaryOperator<Bit> op)
@@ -227,11 +225,11 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                }
 
                /**
-                * Returns a new mutator of the specified width, <b>with all bits set to <code>null</code></b>. Use with care!
+                * Returns a new mutator of the specified length, <b>with all bits set to <code>null</code></b>. Use with care!
                 */
-               public static BitVectorMutator ofWidth(int width)
+               public static BitVectorMutator ofLength(int length)
                {
-                       return new BitVectorMutator(new Bit[width]);
+                       return new BitVectorMutator(new Bit[length]);
                }
 
                /**
@@ -344,17 +342,17 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                        return bits[bits.length - bitIndex - 1];
                }
 
-               public int width()
+               public int length()
                {
                        if (bits == null)
-                               throw new IllegalStateException("cannot obtain a width of an empty mutator");
+                               throw new IllegalStateException("cannot obtain a length of an empty mutator");
                        return bits.length;
                }
 
                private void checkCompatibility(BitVector bv)
                {
-                       if (bits != null && bits.length != bv.width())
-                               throw new IllegalArgumentException(format("BitVector width does not match: %d and %d", bits.length, bv.width()));
+                       if (bits != null && bits.length != bv.length())
+                               throw new IllegalArgumentException(format("BitVector length does not match: %d and %d", bits.length, bv.length()));
                }
        }
 
@@ -385,9 +383,9 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
 
        /**
         * Does test for equality of values/content, shifting the other BitVector by <code>offset</code> to the right.<br>
-        * Therefore <code>offset + other.width() <= this.wdith()</code> needs to be true.
+        * Therefore <code>offset + other.length() <= this.wdith()</code> needs to be true.
         * 
-        * @throws ArrayIndexOutOfBoundsException if <code>offset + other.width() > this.width()</code>
+        * @throws ArrayIndexOutOfBoundsException if <code>offset + other.length() > this.length()</code>
         * 
         * @see Object#equals(Object)
         */
@@ -395,7 +393,7 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
        {
                if (other == null)
                        return false;
-               return Arrays.equals(bits, offset, offset + other.width(), other.bits, 0, other.width());
+               return Arrays.equals(bits, offset, offset + other.length(), other.bits, 0, other.length());
        }
 
        /**
@@ -421,17 +419,49 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
        {
                if (!isBinary())
                        throw new NumberFormatException(this + " is not binary");
-               byte[] bytes = new byte[(bits.length / 8) + 1];
-               for (int i = 0; i < bits.length; i++)
+               byte[] bytes = new byte[(bits.length / 8 + (bits.length % 8 == 0 ? 0 : 1)) + 1];
+               for (int i = bits.length - 1; i >= 0; i--)
                {
-                       if (Bit.ONE == bits[i])
+                       if (Bit.ONE == bits[bits.length - i - 1])
                        {
-                               bytes[i / 8] |= 1 << (i % 8);
+                               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)
         * 
@@ -447,6 +477,20 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                return new BitVector(values);
        }
 
+       /**
+        * Changes a single Bit using the given operation. This can be used to set, clear or flip bits.
+        * 
+        * @param msbIndex           index of the MSB to be changed
+        * @param singleBitOperation the operation to perform on that Bit
+        * @return the resulting, new BitVektor
+        */
+       public BitVector withBitChanged(int msbIndex, UnaryOperator<Bit> singleBitOperation)
+       {
+               Bit[] newBits = bits.clone();
+               newBits[msbIndex] = singleBitOperation.apply(newBits[msbIndex]);
+               return new BitVector(newBits);
+       }
+
        /**
         * Iterate over the {@link Bit}s of the BitVector <b>from MSB to LSB</b> (left to right).
         */
@@ -468,8 +512,19 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
                        @Override
                        public boolean hasNext()
                        {
-                               return pos != width();
+                               return pos != length();
                        }
                };
        }
+
+       public BitVector reverse()
+       {
+               int length = length();
+               Bit[] other = new Bit[length];
+               for (int i = 0, j = length - 1; i < length; i++, j--)
+               {
+                       other[i] = bits[j];
+               }
+               return new BitVector(other);
+       }
 }