Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Nios II Data cache bypass

Hello,

I've created a SOPC component, where Avalon-MM slave port is connected directly to the Dual-Port RAM (1 read port, 1 write port). The hardware writes to the DPRAM and I want to reach that data from Nios. So far, so good, when I need to read data, i issue iord() and everything works fine, but I would like to use a pointer, so it would be easier to read the data:

unsigned int * dma_data = (void *)(PCR_MONITOR_1_MEM_BASE | 0x80000000);
As You can see, I am reading my component BASE address, plus added 31bit cache-bypass bit, but seems like I am wrong somewhere. When I start the CPU, the data read is OK, but when I change the memory contents, the data read out is wrong. I am reading somewhere in cache or there could be other problems?

Thanks.

P.S. I've enabled cache and burst accesses.

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Try defining the pointer as volatile.

    I'd also replace void* with unsigned int* (although I don't think this is the problem)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I tend to define:

    typedef volatile unsigned int v_uint;

    and similar, then use those for reference to hardware data (eg when defining structures that overlay hardware registers).

    Makes it easier to get the 'volatile' in the right place.

    How are you modifying the data?

    You need to ensure that you NEVER access the relevant cache lines.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Eh, just found a dumb mistake. The pointer actually worked fine, I just made a bug with bitmasks, so sometimes, shorter numbers passed the mask and longer ones didn't. This was nothing to do with the pointer or cache.

    However, is that approach is correct? I am doing testing now, but I want to be sure, that such problems won't occour in the future. How do I avoid accessing cache at all?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    So this solution should be fine. I'll do more tests - if anything will go bad, I'll post results here.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Don't forget that this trick will only work as long as you don't use MMU. If you want your code to be portable to a MMU architecture in the future, you might consider using the alt_remap_uncached() function instead of changing bit 31 on the pointer.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Well, I am using the CPU without MMU and even it doesn't run any RTOS :)