Implementing an 8 bit fixed point register
Terry Reedy
tjreedy at udel.edu
Tue Jul 1 18:08:16 EDT 2008
Grant Edwards wrote:
> On 2008-07-01, Terry Reedy <tjreedy at udel.edu> wrote:
>>
>> nickooooola wrote:
>>> Hello to all
>>> I'm about to write a simulator for a microcontroller in python
>>> (why python? because I love it!!!)
>>>
>>> but I have a problem.
>>>
>>> The registry of this processor are all 8 bit long (and 10 bit for some
>>> other strange register)
>>> and I need to simulate the fixed point behaviour of the register,
>>> and to access the single bit.
>> In Python3, I would use a (mutable) bytearray.
>>
>> IDLE 3.0b1
>>>>> reg1 = bytearray((0,)*8) # or *10 for 10 bits
>>>>> reg1
>> bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
>>>>> reg1[1]=1
>>>>> reg1[1]
>> 1
>>>>> tuple(reg1)
>> (0, 1, 0, 0, 0, 0, 0, 0)
>>
>> A bytearray subclass could enforce that all 'bits' (stored as bytes) are
>> 0 or 1, have a customized representation to your taste, and add methods
>> like .flipall().
>
> It seems like implementing ALU operations on such arrays would
> be a lot more work than implementing bit-indexing on a type
> derived on a more "integer" like base. I'm pretty fuzzy on how
> one sub-classes basic things like integers, so maybe I'm all
> wet, and adding __getitem__ and __setitem__ to an integer type
> isn't even possible.
If one only wants bit operations, then the array approach is easy. If
one only wants int arithmetic and all-bits logic, then int approach is
easy. OP did not completely specify needs.
The problem with the int approach is that ints are immutable.
Therefore, if one wants to subclass int to hide the bit masking for the
bit operations, one must override *every* operation one might use,
including all arithmetic and all-bits logic, even when the int operation
gives the correct answer other than the class of the result.
class bits(int):
...
def __add__(self,other):
return bit(self+other)
...
If one does not,
a,b = bits(1),bits(2)
c = a+b #c is now an int, not a bits
So there is a tendency to not subclass and instead either leave the
extra functionality unmasked in repeated code or to put it in functions
instead.
setters = (1,2,4,8,16,32,64, ..., 2147483648)# slightly pseudocode
unsetters = (~1,~2,~4,...~2147483648) # ditto
def bitset(n, bit): return n | setters[bit]
def bitunset(n,bit): return n & unsetters[bit]
thus not getting the nice reg[n] functionality, nor an easy display of
individual bits without callings *another* function.
One the other hand, with mutable arrays, setting bits is a mutation and
so no override of __setitem__ is required unless one wants to be fancy
and enforce setting to 0 or 1.
It is a trade-off.
Terry Jan Reedy
More information about the Python-list
mailing list