Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

interrupt generation

Altera_Forum
Honored Contributor II
1,765 Views

I have an SOPC system with some custom avalon slaves. I would like to generate interrupts to nios with these blocks. I have searched here and on the altera site for documentation on how to implement the interrupt hardware in your avalon components but am coming up empty handed. Can anyone point me in the right direction?:confused::confused::confused:

0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
511 Views

just found the interrupt section in the avalon spec. Not much there, I guess you just assert a line and hold it until your custom slave logic gets told to clear the irq by the cpu. seems pretty simple.

0 Kudos
Altera_Forum
Honored Contributor II
511 Views

there is one catch... 

 

you have to clear the irq-flag manually. 

But if you try to write via pointer on a peripheral module at the END of an interrupt subroutine (=last instruction) and have DATA CACHE enabled (standard, if using NIOS2/f), the data cache will be flushed and the write aborted. 

 

// regular isr static void test_isr(void* context, alt_u32 id) { ... // RESET INTERRUPT at the end of an interrupt (*(long*)PERIPHERAL_BASE) = 0; }  

 

 

So better use 

 

IOWR(PERIPHERAL_BASE, 0, 0); 

 

instead, to bypass the data cache. 

or use the 

 

alt_dcache_flush_all(); 

 

 

statement (# include <sys/alt_cache.h> ). 

 

it took me some time to figure out, why the interrupt flag wasn't cleared if the pointer insturction was the last one, but was cleared if there was an another one after it :D
0 Kudos
Altera_Forum
Honored Contributor II
511 Views

I OR all of the pointers to my Avalon HW blocks with the data cache bypass bit so I don't get this kind of behavior. Hopefully it will avoid me this problem. 

# define DATA_CACHE_BYPASS_BIT 0x80000000 

 

volatile alt_u32* avalon_component_p = (volatile alt_u32*)(AVALON_COMP_BASE|DATA_CACHE_BYPASS_BIT); 

 

This is how I define all of my hw pointers in my C code.  

 

if you have no idea what I'm talking about google up data cache bypass niosII and read their document. I'm still not clear why volatile isn't sufficient but nios provides you with the ability to make the 31st bit '1' in order to force data cache bypassing. 

:)
0 Kudos
Altera_Forum
Honored Contributor II
511 Views

The ldio/stio family of instructions explicitly bypass the data cache. 

Bit-31 provides an alternate method to bypass the data cache. Using the 

bit-31 cache bypass, the normal ld/st family of instructions may be used 

to bypass the data cache if the most-significant bit of the address (bit 31) 

is set to one. The value of bit 31 is only used internally to the CPU; bit 31 

is forced to zero in the actual address accessed. This limits the maximum 

byte address space to 31 bits. 

Using bit 31 to bypass the data cache is a convenient mechanism for 

software because the cacheability of the associated address is contained 

within the address. This usage allows the address to be passed to code 

that uses the normal ld/st family of instructions, while still 

guaranteeing that all accesses to that address consistently bypass the data 

cache. 

Bit-31 cache bypass is only explicitly provided in the Nios II/f core, and 

should not be used for other Nios II cores. The other Nios II cores that do 

not support bit-31 cache bypass limit their maximum byte address space 

to 31 bits to ease migration of code from one implementation to another. 

They effectively ignore the value of bit 31, which allows code written for 

a Nios II/f core using bit 31 cache bypass to run correctly on other current 

Nios II implementations. In general, this feature is dependent on the 

Nios II core implementation.
0 Kudos
Altera_Forum
Honored Contributor II
511 Views

:confused: 

 

Device drivers typically access control registers associated with their 

device. These registers are mapped into the Nios II address space. When 

accessing device registers, the data cache must be bypassed to ensure that accesses are not lost or deferred due to the data cache. 

 

For device drivers, the data cache should be bypassed by using the 

ldio/stio family of instructions. On Nios II cores without a data cache, 

these instructions behave just like their corresponding ld/st 

instructions, and therefore are benign. 

 

for c programmers, note that declaring a pointer as volatile does not 

cause accesses using that volatile pointer to bypass the data cache. the 

volatile keyword only prevents the compiler from optimizing out 

accesses using the pointer. 

 

This volatile behavior is different from the methodology for 

the first-generation Nios processor.
0 Kudos
Altera_Forum
Honored Contributor II
511 Views

Declaring it volatile and making sure that bit 31 is set will ensure that the cache is bypassed. Also, Altera provides HAL functions to remap the address to an uncached address if you don't like doing the bit 31 thing. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
511 Views

Using the HAL functions is in fact better if you want to write code that can be recompiled for a NIOS CPU with MMU. The bit-31 trick won't work in that case IIRC.

0 Kudos
Altera_Forum
Honored Contributor II
511 Views

 

--- Quote Start ---  

Declaring it volatile and making sure that bit 31 is set will ensure that the cache is bypassed. Also, Altera provides HAL functions to remap the address to an uncached address if you don't like doing the bit 31 thing. 

 

Jake 

--- Quote End ---  

 

 

The 'volatile' only ensures that the compiler generate the instruction to write to memory. If the write is cached and the cache isn't write-through (I can't see a definition in the Nios ref book) then the write to memory won't happen until much later. 

 

Additionally you need to leave enough time between the memory write and exiting the ISR for the IRQ to actually have dropped. If you are executing code from tightly coupled memory, the io write requires an Avalon-MM transfer, and you do the write just before returning from the ISR it is possible the ISR will be re-entered.
0 Kudos
Reply