SystemRDL/systemrdl-compiler

Discussion: C Header Generator

ahogen opened this issue ยท 4 comments

Hey Alex (@amykyta3)!

I came across this project maybe a year ago and notice there wasn't a C/C++ generator yet. I tinkered with systemrdl-compiler a bit, then put aside to go work on other things. But generating VHDL and C register definitions has come up again recently at my small company, so I'm looking to pick this up again.

I saw your reddit post from maybe a year back on r/FPGA. It sounded like you might have ideas that you'd be willing to share? If so, I'd love to connect with you somewhere (Matrix chat or here on github?)

The code I have right now is definitely prototype-level, just me tinkering still, but I'm starting to generate C structures of a SystemRDL regfile working. I don't yet have support for arrays (e.g. the fifo_port[8] in the accelera generic example), but it's getting there.

Here's some input/output of what I do have right now: https://gist.github.com/ahogen/f452c8ff8e83c8921de21901f59888d5

I'd love your feedback!

Cheers.

Hey sorry for not getting back to you! I have been traveling recently so have quite a backlog to catch-up to.

I took a quick glance and really like what you have done. Re-opening this ticket and will reply in earnest in the next few days.

No worries! Safe travels!

I took a more in-depth look at what your example generates and it looks quite good! Very tidy.

Some comments in no particular order:

  • I like the idea of defining convenience macros to distinct struct instances as was done here. Good idea - it provides a nice and concise way to reference those nodes in the address space. I may borrow that in the future!
  • Using bit-field structs can be useful, but beware of the side-effects it has in C. Since most processors are unable to perform bit-level accesses, writing to a bit-field will usually imply a read-modify-write operation which is quite inefficient. Consider adding a union & bit-fiddling macros for the bitmask & bit offset of fields so that users can manipulate multiple fields in a register in one operation.
  • This might be a typo? Out-of-place bit-field.
  • Packed structs are a good idea - C standard does not officially define the byte packing rules for structs, so it is left up to the compiler to do whatever it wants. GCC's rules are pretty consistent, but just when I think I have the packing rules figured out, it ends up surprising me.
  • In general, beware of edge-cases in SystemRDL input. Eventually a user will use some of the following constructs and you want you tool to handle it gracefully (graceful handling may include throwing an error which is better than silently generating the wrong code ๐Ÿ˜‰):
    • Single or multi-dimensional arrays of registers
    • Nested addrmap/regfiles that imply deeper structure
    • Separate read-only & write-only registers/fields that share the same address (I've been bitten by this one!)
  • Rather than double-nesting structs, consider typedefing them all individually. This gives the user the flexibility of de-referencing them individually if desired. If you need a robust way of determining the typedef name, see how I did this in the UVM generator, which lets you re-use identical struct definitions cleanly.
ahogen commented

I started taking your feedback into account but haven't had the time to put more effort into it recently. I've dumped the last state of my exporter, very much a WIP, up here: https://gitlab.com/ahogen/systemrd-c-header

Cheers!