hwtypes icon indicating copy to clipboard operation
hwtypes copied to clipboard

Unexpected behavior when using BitVector as index

Open leonardt opened this issue 4 years ago • 1 comments

Not sure if this is something we want to support, since a workaround is to just call int on the BV index value (but then maybe we should add an error check).

Here's an example:

from hwtypes import BitVector, Bit

idx = BitVector.random(2)
x = BitVector.random(4)
x[idx] = Bit.random()

This will always raise the following error:

    def __setitem__(self, index, value):
        if isinstance(index, slice):
            raise NotImplementedError()
        else:
            if not (isinstance(value, bool) or isinstance(value, Bit) or (isinstanc
e(value, int) and value in {0, 1})):
                raise ValueError("Second argument __setitem__ on a single BitVector
 index should be a boolean or 0 or 1, not {value}".format(value=value))

            if index < 0:
                index = self.size+index

            if not (0 <= index < self.size):
>               raise IndexError()
E               IndexError

The reason is that when doing idx < self.size we get an overflow in the less than operator, so it always evaluates to false (since no BV[2] will be less than 0), here's an example:

from hwtypes import BitVector, Bit

idx = BitVector.random(2)
print(idx)
print(0 <= idx)
print(idx < 4)
print(0 <= idx < 4)

will produce

3
Bit(True)
Bit(False)
Bit(False)

If we want to support a BV index, we probably just need to do some extension logic to catch the overflow case in the comparison.

leonardt avatar Oct 15 '20 17:10 leonardt

Generally using a BitVector as a key to set/getitem like this is probably problematic for general objects (since I'd imagine most interfaces expect an int type that will certainly behave differently than a BV in some cases)

leonardt avatar Oct 15 '20 17:10 leonardt