Skip to content

Getter/setter macros #21

@darsor

Description

@darsor

Background

I'm interested in implementing support for fixedpoint fields (per SystemRDL/#188). Specifically, I'd like the ability to call a getter/setter on a field using floating-point values that are automatically translated to/from fixedpoint fields. This proposal is a step in that direction.

Current Access Options

There are currently two ways to get/set the value of a field:

  1. Using bitfield structs
  2. Doing manual memory accesses, bit shifts, and bit masks based on the width/position/mask defines

Proposal

I propose an additional method: Function-like getter/setter macros.

Example

Consider the following:

example.rdl

addrmap top {
    reg {
        field {
            sw=rw; hw=r;
        } f[8];
    } r1;
};

example.h

#include "reg_utils.h"

// Reg - top::r1
#define TOP__R1__F_bm 0xff
#define TOP__R1__F_bp 0
#define TOP__R1__F_bw 8
// vvv proposed macros below vvv
#define TOP__R1__F_get() get_reg32(&top.r1, 0, 0xff)
#define TOP__R1__F_set(value) set_reg32(&top.r1, 0, 0xff, value)
// ^^^ proposed macros above ^^^

// Addrmap - top
typedef struct __attribute__ ((__packed__)) {
    uint32_t r1;
} top_t;

// Instances
#define top (*(volatile top_t *)0x20000000UL)

reg_utils.h

uint32_t reg32_get(volatile uint32_t* reg, uint32_t pos, uint32_t mask) {
    return (*reg >> pos) & mask;
}

void reg32_set(volatile uint32_t* reg, uint32_t pos, uint32_t mask, uint32_t value) {
    uint32_t reg_value = *reg; // read
    reg_value &= ~(mask << pos); // clear
    reg_value |= (value & mask) << pos; // set
    *reg = reg_value; // write
}

Advantages

  1. The getter/setter macros are much less verbose (and less error prone) than manual memory accesses using the width/position/mask defines.
  2. The getter/setter macros don't deal with implementation-defined behavior like bitfields do.
  3. The reg32_get/set functions can be overridden or supplied by the user to work with memories that can't be accessed directly (like a remote device).

Disadvantages:

  1. As written above, the macros only work for a single instantiation (base address) of the addrmap.
    a. Shouldn't be a big issue since multiple instantiations of a regfile can be used in an addrmap with similar effect.
  2. Need to include reg_utils.h in any files that use the macros.
  3. Probably others that I can't think of right now.

Thoughts? Does this fit in the scope of this exporter?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions