I use Forth for interactive debugging and automatic initialization of the FPGA-based hardware (see https://github.com/wzab/AFCK_J1B_FORTH ). Last time I started to add the support for bitfields in the registers accessible via IPbus or Wishbone bus. Below is my implementation of the words used for reading and writing of the bitfields:
\ This file implements bitfield operations
\ It assumes, that we have the bus access
\ words:
\ wb@ ( address -- val )
\ wb! ( val address -- )
\ The bitfield is defined by its mask
\ (the ones correspond to the bits used by the field)
\ and by its shift (position of the LSB in the cell)
: bf@ ( address mask shift -- val )
rot ( mask shift address )
wb@ ( mask shift val )
rot ( shift val mask )
and ( shift val )
swap ( val shift )
rshift ( val )
;
: bf! ( val address mask shift -- )
rot ( val mask shift address )
>r ( val mask shift ) ( R: address )
rot ( mask shift val ) ( R: address )
swap ( mask val shift ) ( R: address )
lshift ( mask val ) ( R: address )
over ( mask val mask ) ( R: address )
and ( mask val ) ( R: address )
swap invert ( val ^mask ) ( R: address )
r@ ( val ^mask address ) ( R: address )
wb@ ( val ^mask oldval ) ( R: address )
and ( val oldval-masked) ( R: address )
or ( val ) ( R: address )
r> ( val address )
wb!
;
The above implementation seems to work, however I'm afraid it is not optimal. Can they be written in a smarter way? It is required, however, that the implementation must be compatible with the Swapforth running on J1B CPU.