How to automatically allocate multiple bit fields into constant length registers?

Hi,

I have to implement control interface in an FPGA connected to the bus with certain width of data bus (let's assume, that it is 32 bits wide). In the c ontrol interface I have to implement some 32-bit registers, and this is not a problem. However additionally I have to implement some bit fields with d ifferent widths (e.g 5 bits, 9 bits and so on).

As description of the FPGA system is still evolving, to avoid continuous ma nual adjustments, I'd like to prepare an algorithm, which could automatical ly find the optimal distribution of those bit fields, so that they fit in t he minimal number of registers.

Of course later on there will be generated VHDL code and address table for the software.

In the first version the above is the only requirement. Later on I consider adding certain constraints, like: "fields A and B should be if possible in the same register", "fields C and D should NOT be in the same register" et c.

Thank you in advance, Best regards, Wojtek

Reply to
wzab01
Loading thread data ...

h certain width of data bus (let's assume, that it is 32 bits wide). In the control interface I have to implement some 32-bit registers, and this is n ot a problem. However additionally I have to implement some bit fields with different widths (e.g 5 bits, 9 bits and so on).

manual adjustments, I'd like to prepare an algorithm, which could automatic ally find the optimal distribution of those bit fields, so that they fit in the minimal number of registers.

r the software.

er adding certain constraints, like: "fields A and B should be if possible in the same register", "fields C and D should NOT be in the same register" etc.

Grab the largest bit field that will fit into the available space and assig n it to the register. Repeat this process until you're done.

Example: Let's say you have five fields that are 9 bits wide; four that ar e 5 bits wide; two that are three bits wide and one that is one bit wide.

So you grab three of the 9 bit fields and assign them to one register, whic h fills up 27 bits of register 1. You can't fit any more 9 bit fields so y ou go to the 5 bit fields. You can fit one of those and that fills up the first 32 bit register.

Now what you have left are: Two 9 bit fields; three 5 bit fields; two 3 bi t fields and one 1 bit field. So you grab the two 9 bit fields and then tw o 5 bit fields for 28 bits. You're can't fit anymore 5 bit fields so you g rab one of the 3 bit fields and then since you can't fit anymore 3 bit fiel ds you grab the 1 bit field to fill up the remaining space in the 32 bit fi eld.

Kevin Jennings

Reply to
KJ

Hi,

the registers are synthesized in the FPGA fabric from FFs, aren't they? If so, you could simply omit unused bits. The FFs get optimized away, they don't exist physically (this is at least done on ASICs, with a fixed default value for reading).

Generally, I wouldn't micro-optimize the register space but try to arrange everything in a logical and debug-friendly order that is least likely to change in future revisions, to avoid later surprises with the SW compiler optimization.

--------------------------------------- Posted through

formatting link

Reply to
mnentwig

That sounds like a recipe for the World's Most Disorganized Interface.

Whoever has to write the software to interface with those registers will be Most Displeased with you if you take that approach -- the first time that you add just one bit to one of those registers and cause your nifty automatic algorithm to completely relocate everything, they'll be even _more_ displeased with you.

This is something that you really need to give some thought to laying out logically. It's probably worth a bit of extra address decode now to make the product future-proof.

My suggestion is to lay out the registers so they conform (as best as you can) to the following rules:

0: Document everything you do. Making this interface clear and well understood by the software team is going to be a critical part of your project success. Don't mess it up. Having your software team review a proposed interface before you commit to it is a good idea.

1: Related bits go in related registers. I.e., "motor on" and "baud rate" do not belong together.

2: Related sets of registers go together in contiguous, or mostly contiguous blocks. I.e., if you have comms stuff and motor drive stuff, don't intermix them -- keep them separate.

3: Don't be afraid of unused bits. Set your code up so that writes to unused bits are ignored, and reads always read back the same thing (0 is good). Later, if you have to add more functionality, try to make the expanded interface work "the old way" if a previously unused bit is set to

4: Don't be afraid of swaths of unused registers. With a 32-bit address space, you can dedicate 1kB blocks to each function, and just have lots of unused addresses (i.e., motor control maps to 0x0000, comms to 0x0400, etc.).

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

t
s
t

"

o

f

Well, that's how I have worked all the time before. This worked good until I had to extend a bitfield so that it stopped to fit in the register with other neighbouring bit fields.

So now I'm investigating possibilities to optimize the control logic as muc h as possible, with all changes hidden behind the intermediate software lay er. The software will approach registers and bitfields via their symbolic names obtained from the address tables (using the IPbus approach -

formatting link
Table , however IPbus requires that you specify the register name together with bitfield name, I'd like to fully hide it.)

Of course there must be at least one ID register with known location contai ning a unique magic number, allowing to make sure that we are talking to th e appropriate board with appropriate firmware version...

May be this is just a crazy experiment...

Thanks & regards, Wojtek

Reply to
wzab01

W dniu poniedzia?ek, 22 grudnia 2014 20:00:19 UTC+1 u?ytkownik wz snipped-for-privacy@gmail.com napisa?:

To make the whole idea even more crazy, I'could imagine, that the final pla cement of bit fields in registers could be optimized basing on automatic analysis of control procedures implemented in software. E.g. bit fields which are often changed together without placing "barriers" enforcing the particular order of operation ("hw.dispatch()" in the IPbus) , can be grouped in the same register, so that they are written in single o peration. If they do not fit in a single register, they should be placed at consecuti ve locations so that they can be written by block operation and so on...

Regards, Wojtek

Reply to
wzab01

Hint: The concatenation operator ## of the C preprocessor is your best friend.

It allows to generate fairly complex access macros.

Completely separating register name and bitfield name is IMO not practical, as the programmer wants to combine multiple fields of the same register into one bus access, which is usually slow.

The compiler cannot optimize this when hardware control registers are "volatile".

I'd go out of my way to make the hardware as programming-friendly as possible. Embedded debugging is expensive, a couple of gates cost nothing (depends).

For example, shadow registers or even configuration banks can make the programmer's life easier, when a single bit write triggers an atomic reconfiguration of a whole hardware block.

Still about "crazy", I've seen some pretty sophisticated register management infrastructure been used in production that synthesized the register code, generated software access scripts, set up test automation GUIs, generated register list documentation etc. Maybe the ASIC folks are more paranoid about "small" mistakes, it's just a metal mask fix...

--------------------------------------- Posted through

formatting link

Reply to
mnentwig

(snip)

With current addressing spaces, unless this is a very unusual system, you don't need or want that kind of optimization. For one, as you note, fields might expand. There are many systems around with unusal bit positions when something expanded and there weren't bits to expand into.

As someone noted, register bits that aren't used will be optimized out at syntheis. (If you are lucky, there is a warning message.) The only cost is address space, which in most systems is cheap.

But there may be some unusual systems, in which case you will have to explain in more detail.

-- glen

Reply to
glen herrmannsfeldt

I think that's not what I meant. For example, take this C example (don't read from hardware without good reason, this is only an example)

volatile void* p = 0xDEADBEEF; // hardware register

*p = 0x1; *p |= 0x2; *p |= 0x4; *p |= 0x8;

where the above commands would result from bitfield access macros. Assuming the order does not matter, it can be simplified to a single bus access

*p = 0xF;

but the C compiler can't do this for me because of "volatile". That means, bit fields and registers can't be separated in the code. Change the distribution of bitfields across registers and the code will have to be rewritten.

--------------------------------------- Posted through

formatting link

Reply to
mnentwig

make that unsigned short * ...

--------------------------------------- Posted through

formatting link

Reply to
mnentwig

W dniu wtorek, 23 grudnia 2014 00:41:28 UTC+1 u?ytkownik mnentwig napi sa?:

ge

be

That's exactly what I meant writing "the final placement of bit fields in r egisters could be optimized basing on automatic analysis of control procedu res implemented in software". BTW the IPbus implementation coalesces such operations, transforming them i nto a single access on the fly (all operations issued between calls to disp atch() may be treated that way).

--
Regards, 
Wojtek
Reply to
wzab01

into a single access on the fly (all operations issued between calls to disp=

Thanks, I'll have a look at the programming API.

I've been thinking myself about abstracting register access, collect all bits in a temporary stack variable and use some finalizer (probably similar to your "dispatch") to execute the bus access. Manually collecting all bit fields per register as in my code is boneheaded, it just happens to work in real life.

Debugging would be my main concern, but then the manual version (as in my example) isn't exactly maintenance-friendly either.

I could imagine that with an IP-based connection there is more incentive to optimize the bus access. With everything on one chip, it's a concern but I wouldn't expect it at the top of my priority list.

By the way, the packing problem itself could actually be some NP-complete integer programming thing (just guessing):

formatting link
But simple heuristics (earlier posts) would surely work well enough.

--------------------------------------- Posted through

formatting link

Reply to
mnentwig

that can also makes the decoding a bit easier

I'd add that keeping something like a number on a four bit boundary makes it a bit more human readable

and having bitset/bitclear for certain registers can make the code smaller and life a bit easier

-Lasse

Reply to
langwadt

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.