Skip to main content

A framework for structured bitfield processing

Project description

bffl

Bit Fields For Lumberjacks

lumberjack

bffl is a high-performance bit field protocol framework for working with packed binary data. It's ideal for scenarios requiring precise control of bit arrangements, such as verilog interfaces and arbitrary bitfield manipulations. Your protocol is expressed concisely using compositions of ints, structs, arrays, and user-defined types.

Comparison to ctypes

Tool Model Primary Purpose Implementation
ctypes C/C++ types Interface with C/C++ code, model C/C++ datatypes Python, C++
bffl Bit fields Model arbitrary bit-aligned datatypes and interfaces Python
  • Use ctypes for interfacing with C/C++.
  • Use bffl for full control over bit-aligned binary protocols.
  • Use both for combined functionality.

Comparison to C++ Bitfields

C++ bitfields optimize for performance and byte alignment, often disregarding explicit bit control. bffl offers full control over bit allocation, making it ideal for protocol implementations and verilog.

// In C++, struct size is implicitly padded:
struct Example {
    uint8_t a : 5;
    uint8_t b : 13;
};  // Size may not be 18 bits due to padding

// In bffl:
class Example(metaclass=metastruct):
    a: uint(5)
    b: uint(13)

In bffl, structs are exactly the sum of their members' sizes, with no implicit padding. An array of 7 7-bit integers occupies precisely 49 bits (uint(7)[7].size_ == 49).

Ease of Use

raw_data_source = sequence_of_integers_from_somewhere()

class parrot_struct(metaclass=metastruct):
    status: uint(2, {'dead': 0, 'pining': 1, 'resting': 2})
    plumage_rgb: uint(5)[3]

death_enum = uint(3, {
    'vorpal_bunny': 0,
    'liverectomy': 1,
    'ni': 2,
    'question': 3,
    'mint': 4,
    'not_dead_yet': 5,
})

class knight_struct(metaclass=metastruct):
    name: utf8(20)
    cause_of_death: death_enum

class quest_struct(metaclass=metastruct):
    quest: uint(3, {'grail': 0, 'shrubbery': 1, 'meaning': 2, 'larch': 3, 'gourd': 4})
    knights: knight_struct[3]
    holy: uint(1)
    parrot: parrot_struct

def get_dead_parrot_quests(raw_data_source: Sequence[int]) -> Iterator[str]:
    data = quest_struct()
    status = data.parrot.status

    for data.n_ in raw_data_source:
        if status == 'dead':
            yield data.json_

for jstr in get_dead_parrot_quests(raw_data_source):
    print(jstr)

Interoperability

Fields have read/write properties exposing data:

Attribute Description
n_ Raw bits as an int (unbounded size)
v_ Data value as int, float, str, list, dict
json_ Data value as a JSON string

Performance

Performance is achieved by symbolic processing during interface allocation, reducing runtime overhead. A bound field computation typically involves a shift-and operation.

class MyRegister(metaclass=metastruct):
    rtype: uint(2, enum_={'grail': 0, 'shrubbery': 1, 'meaning': 2, 'larch': 3})
    stuff: uint(3)
    junk: uint(1)

class MyProtocol(metaclass=metastruct):
    header: uint(5)
    a: MyRegister
    b: MyRegister
    c: MyRegister

def look_for_fives(datastream: Sequence[int]):
    buffer = MyProtocol()
    bstuff = buffer.b.stuff

    for n in datastream:
        buffer.n_ = n
        if bstuff == 5:
            handle_5()

Trailing Underscore Convention

Non-field attributes use a trailing underscore, allowing full use of the field namespace.

System Verilog Support

bffl uses Python semantics for indexing and slicing but includes svreg for System Verilog slice semantics.

r = svreg(28)(0xabadbee)
r2 = r[15:4]
assert r2 == 0xbad
r2.v_ = 0xead
r[3:0] = 0xd
assert r == 0xdeadbee

Related Projects

Here is a comparison grid of various bitfield-related libraries with verified licenses:

Library Description Primary Purpose
bitvector Bit vector implementation with BitField descriptor for sub-byte bit addressing Address and manipulate bits in integer words
bfield Convenient bit fields for int subclasses Define and manipulate bitfields
ctypes-bitfield Bitfields with ctypes integration Interface with C/C++ bitfields
sparsebitfield Manage sparse sets of large integers Efficiently manage large sets of bits
bitfield Sparse sets of large integers optimized for sequential integers Handle large, sparse integer sets
named_bitfield Define named bitfields for easier access and manipulation Named bitfields
bitstring Supports slicing and manipulating bit strings Handle and manipulate bit strings

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bffl-0.2.0.tar.gz (18.3 kB view hashes)

Uploaded Source

Built Distribution

bffl-0.2.0-py3-none-any.whl (17.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page