chipsalliance / Cores-VeeR-EL2

VeeR EL2 Core
https://chipsalliance.github.io/Cores-VeeR-EL2/html/
Apache License 2.0
243 stars 73 forks source link

How to fix load region prediction error #36

Closed wenjiegong closed 2 years ago

wenjiegong commented 2 years ago

Code snippet address : instruction 20003d84: auipc x16, 0xfffc 20003d88: lw x16, 776(x16)

'lw' caused the load region prediction error. Because the value(20003d84+0xfffc000=2ffffd84) of x16 was not in the region of DCCM.

Is there a workaround to avoid the error? Thanks!

I use EL2 v1.4.

aprnath commented 2 years ago

Where have you installed the DCCM ? (What are the value of RV_DCCM_REGION in the common_defines.vh file?) What is the value in MSCAUSE for the exception ?

Region prediction exception (MCAUSE==5, MSCAUSE==5) occurs if the effective address (x16 +776 in your case) falls in a different region than the base address (x16 in your case), and one of the two regions happens to be an 'internal' region (containing DCCM or PIC).

Given your values above, this will happen if the DCCM or PIC is mapped to region 3, and your code is executing at the top of region two and your pointer generation is using current PC+relative to form the pointer. Can you confirm this?

The simplest workaround I can suggest is to form the pointer address in such a way to not need region crossing. If the DCCM is in region 3 make sure X16 is fully within region 3, and provide the appropriate offset. The EA for the load above is 0x3000008c. So best is to set up the DCCM base pointer to the start of the DCCM - at 0x30000000, for example. Use a "li" mnemonic, since your DCCM base is a known constant, instead of "la" - the latter tends to be PC relative.

If the address/offset mechanism is not in your control (compiler tries to be smarter), then avoid the text/code section to be adjacent to the DCCM (within 4K of the DCCM start/end).

wenjiegong commented 2 years ago

Hi aprnath, Thansk for the quick response!

Thanks!

wenjiegong commented 2 years ago

Hi aprnath,

I checked my memory map: ICCM start addr: 0x2000_0000, length: 256KB DCCM start addr: 0x3000_0000, length: 512KB

.data section start addr: 0x3000_0000

The text/code section has been far away from DCCM.

What's your opinion? Is there any else workaround?

BTW, We used to locate ICCM and DCCM in the same region, but it failed to copy .data section from ICCM to DCCM in bootloader.

aprnath commented 2 years ago

Consider locating DCCM not at the start of region 3, but at least 4K away from the start or end of region. So maybe 512K away from the start/end of region 3 would be a good choice. This will make sure that the address pointer and the effective address will always be in the same 256M region. I think this would be a robust solution. My suggestion of the placement of text/code relative to DCCM data is baseless and invalid. This does not have to anything to do with the data and text/code relationship. Rather it has to do with the fact that if you don't have the ability to form the DCCM base pointers via assembly, then you must ensure that the DCCM start address is placed such that the maximum ld/st offset values don't result in region crossings.

Regarding your failure to copy between ICCM and DCCM : this is really not possible because ICCM is NOT visible to load/stores. ICCM can only be accessed by the DMA port, or the debugger - apart from fetch read-only accesses.

You can jury-rig a mechanism to redirect selected address from the Ld/St bus back through the DMA port, which will allow you to access ICCM via Ld/St. The provided testbench has an example of this selected muxed loopback strategy.

wenjiegong commented 2 years ago

Hi aprnath,

Thanks for your help!