SystemRDL / PeakRDL-regblock

Generate SystemVerilog RTL that implements a register block from compiled SystemRDL input.
http://peakrdl-regblock.readthedocs.io
GNU General Public License v3.0
52 stars 42 forks source link

External register fields in structs #84

Closed mpriestleyidex closed 7 months ago

mpriestleyidex commented 10 months ago

If I define an external register containing multiple fields:

reg ER {
  field { hw = rw; sw = r; } f1[15:0];
  field { hw = rw; sw = r; } f2[31:16];
};

external ER ER @0;

the generated hwif_in struct contains a flattened rd_data[31:0] for the whole reg. I cannot assign the fields individually.

Clearly I can do:

assign hwif_in.ER.rd_data[15:0] = val1;
assign hwif_in.ER.rd_data[31:16] = val2;

but this requires me to know the layout of the register in my RTL, which kind of defeats the purpose.

Can I instead have hwif_in.ER.f1.rd_data[15:0] etc?

mpriestleyidex commented 10 months ago

Actually, I think rd_data wants to contain fields, not the other way around:

typedef struct packed {
  logic [15:0] f2;
  logic [15:0] f1;
} MAP__ER__data_t;

Then I can:

assign hwif_in.ER.rd_data = '{f1: val1, f2: val2};
amykyta3 commented 10 months ago

Agree that in this case, it would be useful to expose the fields as packed structs. Since they are external, you are basically instructing the compiler to not implement them as part of the internal regblock. For that reason, I would also include any reserved bit space in between fields since it is an intentional break in the register abstraction.

Note that in some situations it would not be possible to fully support a packed struct. For example in wide registers (regwidth > accesswidth), the exposed external register data port would remain as acceswidth bits wide. I suppose even then I could implement it as a packed union though...

amykyta3 commented 7 months ago

Will be fixed in upcoming release