Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,145 Views

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.
0 Kudos
7 Replies
Altera_Forum
Honored Contributor I
64 Views

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
Honored Contributor I
64 Views

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
Honored Contributor I
64 Views

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
Honored Contributor I
64 Views

Not using the address below 2^31 for that area.

Altera_Forum
Honored Contributor I
64 Views

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

Altera_Forum
Honored Contributor I
64 Views

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
Honored Contributor I
64 Views

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

Reply