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.
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.
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?
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.