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

[BUG] memory size is not calulated correctly #110

Open arnonsha opened 5 months ago

arnonsha commented 5 months ago

Describe the bug First time I'm trying to add a memory instance: When trying to add a 32x1024 memory, I get an error message. The memory size reported in the message is wrong

RDL code:

    external mem mymem {
       memwidth = 32;
       mementries = 1024;  // = 0x400
       sw = rw;
    } mem1 @0x400;

Error message:

error: Address offset +0x400 of instance 'mem1' is not a power of 2 multiple of its size 0x1000. This is required by the regblock exporter if a component is external.
    } mem1 @0x400;

What is 0x1000 ? Is that the alignment needed ? When using address 0x1000 instead 0f 0x400 I get no error but the size of the memory is 0x400 so 0x000, 0x400, 0xc00 should be 'aligned' addresses. Am I missing something here ?

tool version

0.22

amykyta3 commented 5 months ago

Addresses are in units of bytes. Since your memory is 32-bits wide (4 bytes), and has 0x400 entries, 4 * 0x400 = 0x1000

arnonsha commented 5 months ago

Thank you for explaining.

Looking at the verilog implementation (when using address 0x1000) decoded_reg_strb.mem1 = cpuif_req_masked & (cpuif_addr >= 13'h1000) & (cpuif_addr <= 13'h1000 + 13'hfff);

Can you also explain where the address limitation is coming from based on the adr decoding implementation above ? As I wrote above, I believe 0x000, 0x400 0x800, 0xc00 are all aligned addresses for this memory block

amykyta3 commented 5 months ago

No since the size of the memory block is 0x1000 (4 * 0x400), then only address offsets that are multiples of 0x1000 are aligned, so @ 0x0000, @ 0x1000, @ 0x2000, etc.

arnonsha commented 5 months ago

Sorry, I should have better explain my question: If the strobe implementation checks the entire address range between the memory base address and the base address plus the memory size, why restrict the user to aligned addresses only? I mean what would happen if I use 0x400 as my memory base address (assuming the compiler lets me) ? I guess the strobe then would be: decoded_reg_strb.mem1 = cpuif_req_masked & (cpuif_addr >= 13'h400) & (cpuif_addr <= 13'h400 13'hfff);

We can argue about what is more efficient in terms of gate count after synth, but why limiting the user ?