Implementing an 8 bit fixed point register

Grant Edwards grante at visi.com
Tue Jul 1 16:07:07 CEST 2008


On 2008-07-01, nickooooola <nick83ola at gmail.com> 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,

Somebody posted a class that impliments fixed-width integer
types a while back.

> and to access the single bit.

The bitwise operators &, |, ~, ^ all work just like they do in C.

You can write methods to dip those in syntactic sugar if you
want.

> f.x. (this is a pseudo python session, only for understanding)
>
>>>> reg1 = fixed_int(8)
>>>> reg2 = fixed_int(10)
>>>> reg1[0].set()
> or
>>>> reg1[0] = 1 # or True? how to rapresent a binary bit
>>>> reg1[0]
> 1
>>>> reg1[1]
> 0
>>>> reg1[9]
><exception .... blah blah not in range>
>>>> reg2 = 0x7FE   # in binary  11111111110 , or 11 bit long
>>>> reg2
> 0x7FE
> #or 1111111110, the memorization truncate the upper bits ( or perhaps
> generate an exception?)
>>>> reg2 += 0x02 #the result is 10000000000, again not contained in 10 bit
>>>> reg2
> 0x00
> # truncated again
>>>> myprocessor.flags['z']
> 1
> # or True? Z flag indicated an overflow in arithmetic operations
>
> Is possibile to do so in python?

Yes.  Everything shown above is possible.  If you really want
to get clever, you'll want to read up on the __setattr__,
__getattr__, __getitem__, and __setitem__ object methods.

They'll allow you to define special handling for the semantics
below:

  foo.something = x          # calls foo.__setattr___('something',x)
  x = foo.something          # calls foo.__getattr___('something,)

  foo[n] = x                 # calls foo.__setitem__(n,x)
  x = foo[n]                 # calls foo.__getitme__(n)
  
In the latter two cases, you can support slicing if you want.
That could allows you to grab a "bitfield" out of a register:

  x = processor.regA[4:7]   # get bits 4,5,6
  
  processor.regA[4:7]       # set bits 4,5,6
  
Just remember that in Python slices are traditionally half-open
intervals -- they don't include the "right" endpoint.  That's
going to confuse people who are more used to reading processor
data sheets where bit-ranges are traditionally closed
intervals.  You _could_ implment your __[sg]etitem__ slice
handling so that they're treated as closed intervals. That will
be a lot more intuitive to people used to dealing with
microprocessor register definitions, but could confuse an
experienced Python programmer.

Writing methods for __setattr__ and __getattr__ is a little
tricky. It's very easy to end up with infinite recursion.  It's
not that hard to fix/avoid, but it takes a while to get the
hang of it.

-- 
Grant Edwards                   grante             Yow!
                                  at               
                               visi.com            



More information about the Python-list mailing list