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

Nios II hanging/crashing on PIO write?

I'm using a DE0-Nano board with a design which includes a NIOS II processor with a PIO module to flash the board's LEDs. 

 

No problems there - processor works, LEDs flash, jolly good. 

 

But, I then did the following: 

 

- Added a second PIO, 24-bit width output-only, and connected this to a custom hardware module in the project bdf 

 

- Added a third PIO, 1-bit width input-only, with interrupt enabled, and connected this to a custom hardware module the project bdf (a clock signal). 

 

I made no changes to the NIOS II code, and so I tried to build, download and run the program just to make sure everything still worked.  

 

Sure enough, it doesn't. In Debug mode, I see the NIOS II processor seems to lock up the moment it gets to any IOWR routine to write to the PIO for the LEDs (again, there is no code referencing the other PIOs, beyond what is generated by the BSP). 

 

What could be causing the CPU to lock up? The lack of an ISR for the interrupt I just created? I thought the interrupt was disabled until I registered it.
0 Kudos
15 Replies
Altera_Forum
Honored Contributor I
133 Views

Hi again, 

 

Further to my last post, I've found the original code works properly if I leave the new 24-bit and 1-bit PIO modules unconnected. 

 

As soon as I connect either PIO to its relevant custom hardware module in the block schematic, the code will no longer function. 

 

Any suggestions? There is precious little on the web about using multiple PIO modules in a NIOS II design. Presumably because they usually just work, haha. :)
Altera_Forum
Honored Contributor I
133 Views

Several ideas:[list][*]the address mapping changed and the software you compiled is still using the old address map that is no longer valid 

[*]your new peripherals are using a clock that isn't running and this locks the Avalon bus 

[*]the new compiled FPGA project doesn't meet timing requirements[/list]
Altera_Forum
Honored Contributor I
133 Views

Is this a Qsys or SOPC Builder based design? If it's Qsys then perhaps you are writing into space due to a mismatch between the software and hardware (Qsys is less forgiving when it comes to writing into space). I recommend putting the system ID peripheral into your system to help catch some of the mismatches Daixiwen mentioned. 

 

I would also try simulating the design. That should give you more insight into what is causing the issue. 

 

Last but not least, how much space do you have left for the stack and the heap? Could be that you were on the hairy edge of running out and the code change with the new PIO put you over.
Altera_Forum
Honored Contributor I
133 Views

I'm also having a very similar issue to this. The while(1) loop within my program runs perfectly for the first iteration, but then just hangs on the IOWR_ALTERA_AVALON_PIO_DATA macro the second time around.  

 

Any ideas why it would work the first time but not the second? I'm not changing any base addresses or anything. 

 

Incidentally, when the system hangs, I have to redownload the .sof onto my board for it to run again, otherwise I get an error saying "'Launching [project name] Nios II Hardware configuration' has encountered a problem. Downloading ELF Process failed".
Altera_Forum
Honored Contributor I
133 Views

Actually what you are describing might be something different. If your while (1) loop is tight it could be the debugger having problems stepping through it. I'm not sure what actually happens when that bug is reached that I'm referring to but the symptoms you described sound just like it.

Altera_Forum
Honored Contributor I
133 Views

Thanks BadOmen, I think I sorted it out anyway. As my PIO out was running with a 50kHz pll clock, compared to my 50MHz system clock, I think the system was probably waiting for 1000 iterations before it wrote the data (would explain why the first one was output fine, as the two clocks would then have been in sync). I've since amended the system to both run off the same clock and the data is output fine. Although, I have a horrible feeling that I'm gonna get a 1000x repetition of each of the values I'm trying to read...

Altera_Forum
Honored Contributor I
133 Views

 

--- Quote Start ---  

Thanks BadOmen, I think I sorted it out anyway. As my PIO out was running with a 50kHz pll clock, compared to my 50MHz system clock, I think the system was probably waiting for 1000 iterations before it wrote the data (would explain why the first one was output fine, as the two clocks would then have been in sync). I've since amended the system to both run off the same clock and the data is output fine. Although, I have a horrible feeling that I'm gonna get a 1000x repetition of each of the values I'm trying to read... 

--- Quote End ---  

 

 

I am also having the same issue as that of el07...but my system clock and the PIO clock are the same.Still i have this problem.What can be the reason for the Nios hanging when attempting to write a PIO.?
Altera_Forum
Honored Contributor I
133 Views

Make sure to use the HAL driver libraries for the PIO instead of accessing it directly. If you are accessing it directly you might be writing to the wrong location causing the master to lock up.

Altera_Forum
Honored Contributor I
133 Views

I am using the altera_avalon_pio_regs.h files for the write operation macros.Still i got the problem of locking up.

Altera_Forum
Honored Contributor I
133 Views

Are you passing in the base address of the PIO defined by system.h? If so I would look at the base address macro in system.h and compare it against what is shown in the Qsys UI to make sure they match.

Altera_Forum
Honored Contributor I
133 Views

 

--- Quote Start ---  

Are you passing in the base address of the PIO defined by system.h? If so I would look at the base address macro in system.h and compare it against what is shown in the Qsys UI to make sure they match. 

--- Quote End ---  

 

 

I have made sure that both the address specified in the Qsys and the system.h are same.
Altera_Forum
Honored Contributor I
133 Views

 

--- Quote Start ---  

Are you passing in the base address of the PIO defined by system.h? If so I would look at the base address macro in system.h and compare it against what is shown in the Qsys UI to make sure they match. 

--- Quote End ---  

 

 

I have made sure that both the address specified in the Qsys and the system.h are same. 

 

In my Qsys i have a 16 bit PIO which i configured it as bidirectional.Will it create any problem?
Altera_Forum
Honored Contributor I
133 Views

No that shouldn't have caused a problem. When the PIO is bidirectional with a single tristate bus that connects off-chip there is a direction register that you write to in order to switch between input and output. If you have it set to input but attempt to write data I forget what the behavior is (probably stores the data but continues being an input) but I wouldn't expect that to cause a lockup. I recommend simulating the design, that's what I typically do when debugging system deadlocks. You'll want to look at the Nios II masters, the PIO slave port, and if you have any bridges between the CPU and PIO look at those in the simulation as well. This will let you determine where in the system the lockup occurs. Sometimes I also include the slave port of the memory I'm executing code out of as well. To track what the CPU is doing during the simulation I often look at the objdump file for the executable and correlate the addresses that the instruction master issues to the addresses in the objdump to figure out approximately which instructions are being executed. 

 

Also if you are using a small on-chip RAM to store your code, you might want to try temporarily increasing the size of the memory if you have room just in case you are running into a stack and heap collision.
Altera_Forum
Honored Contributor I
133 Views

hai BadOmen, 

 

Can you tell me a little bit in detail of the bidirectional PIO's.
Altera_Forum
Honored Contributor I
133 Views

You can find the PIO component documentation here: https://www.altera.com/content/dam/altera-www/global/en_us/pdfs/literature/ug/ug_embedded_ip.pdf 

 

The PIO supports a combined input/output mode in two ways. One mode has separate input and output ports so that when you write to the data register it is sent to the output and when you read from the data register the input is returned to the requesting master. The other mode uses bidirectional data which means that a single tri-state interface is exposed (Verilog it's inout, I forget what VHDL calls it) which means you have to write to the direction register to control whether that tri-state port drives out the data or if it reads data. Bidirectional ports can only drive a 0, drive a 1, or be an input so that's why you have to select it's direction by setting up the direction register.
Reply