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++
12652 Discussions

Problem with IORD and IOWR instructions

Altera_Forum
Honored Contributor II
5,127 Views

Dear all, 

 

I have a qsys system composed of two NIOS that can access a shared memory (data masters are connected to the memory),  

when I use the instructions IORD and IOWR I don't obtain the right value 

The shared memory is intialised with a hex file that contains tha value 6 at the adress 0 

 

But when NIOS1 does: IORD (SHAREDMEM_BASE, 0x0) I obtain in the console a wrong value : 6c6c6cFc!!! 

Also when the first NIOS writes a value at the @0 using IORD and then the NIOS 2 tries to read this value, I obtain a wrong value 

 

I'm using NIOSII SBT 11.1 

 

Please anyone can help me?? is there a functioning example using these two instructions?
0 Kudos
18 Replies
Altera_Forum
Honored Contributor II
2,240 Views

Are you sure that the address is correct? 

You can put Signaltap probes on the shared memory's Avalon interface and monitor what the CPUs are doing when trying to access it.
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

Are you sure that the address is correct? 

You can put Signaltap probes on the shared memory's Avalon interface and monitor what the CPUs are doing when trying to access it. 

--- Quote End ---  

 

 

Yes I'm sure this is the adress specified by qsys (also defined in system.h)
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

please is that any option to add to the on chip memory in qsys so that the NIOS can read the written value by another processor??

0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

There is nothing special to do, it should just work. As I suggested, use Signaltap to debug your system. 

By the way is your project properly constrained and does it meet all timing requirements?
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

There is nothing special to do, it should just work. As I suggested, use Signaltap to debug your system. 

By the way is your project properly constrained and does it meet all timing requirements? 

--- Quote End ---  

 

 

 

How to verify timing requirements?? 

Can I send you the project to tell me if it's OK? 

 

Many Thanks
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Hi, 

 

please can you tell me if my SW code is correct: 

 

in each on chip memory of NIOS I write the same code: 

 

# include <stdio.h> 

# include "system.h" 

# include <stdlib.h> 

# include "io.h" 

 

# define SHAREDMEM_BASE 0x00008000 

 

int main() 

{ int id,data; 

int i,j; 

int temp; 

id = ALT_CPU_CPU_ID_VALUE; 

 

printf("Hello from Nios II! %d \n",ALT_CPU_CPU_ID_VALUE); 

 

 

 

if (id==1) {IOWR(SHAREDMEM_BASE, 0, 0x9); 

data = IORD(SHAREDMEM_BASE, 0x0); 

printf("data read = %x \n",data); 

 

else { 

for (i=0;i<5000000;i++) j++; //to assure that NIOS1 has written the data 

temp=IORD(SHAREDMEM_BASE, 0x0); 

printf("temp read = %d \n",temp); 

 

return 0; 

 

 

When executing this code I obtained : 

data=9 which is right  

temp=1734829426 which is false !!! 

 

What's wrong in this code??
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Are you sure that your delay is enough to guarantee that the first CPU has written the data before the second one reads it? How do you program the two CPUs? 

Alternatively you could have the second CPU wait in a loop until it reads 9 from the shared memory and see if it ever gets out of the loop. 

For the timing requirements, have a look at the critical warnings in Quartus. If you have a "Timing requirements not met" critical warning then you have a timing problem that could lead to all kinds of bugs.
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Are you compiling with optimizations enabled? I could see your delay loop getting optimized away since variables i and j are not used. Compilers look for code like that a remove it when optimizations are enable since it's a waste of CPU cycles. 

 

In general using delays as synchronization points is very error prone. You should use flags in shared memory... or better yet use a mutex since if you work with a system with multiple data widths sharing information through shared memory is not safe either due to race conditions.
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

Are you sure that your delay is enough to guarantee that the first CPU has written the data before the second one reads it? How do you program the two CPUs? 

Alternatively you could have the second CPU wait in a loop until it reads 9 from the shared memory and see if it ever gets out of the loop. 

For the timing requirements, have a look at the critical warnings in Quartus. If you have a "Timing requirements not met" critical warning then you have a timing problem that could lead to all kinds of bugs. 

--- Quote End ---  

 

 

 

When I change the code of else like this: 

 

while (IORD(SHAREDMEM_BASE, 0x0) != 9) j++; 

temp=IORD(SHAREDMEM_BASE, 0x0); 

printf("temp read = %d \n",temp); 

 

The CPU2 remain in while loop and never gets out,  

This assure that he can't read the value written by CPU1 or that the shared memory hasn't changed 

 

The project meets the timing requirements, 

 

so please any idea to solve this??
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

Are you compiling with optimizations enabled? I could see your delay loop getting optimized away since variables i and j are not used. Compilers look for code like that a remove it when optimizations are enable since it's a waste of CPU cycles. 

 

In general using delays as synchronization points is very error prone. You should use flags in shared memory... or better yet use a mutex since if you work with a system with multiple data widths sharing information through shared memory is not safe either due to race conditions. 

--- Quote End ---  

 

 

Hi BadOmen, 

 

where enable the optimizations? I'm using the default setting of NIOS II SBT tool to compile both codes 

I want in a first step be sure of the functioning of IORD and IOWR and then use the mutex to access the shared memory 

any help will be appreciated, 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

Hi BadOmen, 

 

where enable the optimizations? I'm using the default setting of NIOS II SBT tool to compile both codes 

I want in a first step be sure of the functioning of IORD and IOWR and then use the mutex to access the shared memory 

any help will be appreciated, 

Thanks 

--- Quote End ---  

 

 

I typically work from the command line so I forget where it is but a debug profile would normally contain -O0 optimization (i.e. no optimization). For that updated code that polls for 9 to be read back from memory try making the 'j' variable volatile, regardless of whether optimizations are enabled or not that should prevent the loop from being removed. 

 

Also are you sure your both processors are actually running code? Each CPU should have it's own BSP (can't have them both sharing read/write, heap, and stack regions) so you should be able to run them independent of eachother to make sure they execute code properly up to a certain point. Once that's verified then you can download the code as a multi-download group (whatever it's called in the IDE). I normally find it easier to coordinate multiple processor downloads from the command line like this: 

 

nios2-download -i 0 -g <elf1.elf> 

nios2-download -i 1 -g -r <elf2.elf> 

nios2-terminal -i 0 

nios2-terminal -i 1 

 

The -i lets you pick which Nios II JTAG debug module/JTAG UART you are using. The -g tells nios2-download to start executing code and -r means reset the target. Normally I open one terminal window per command shell so that I can watch the output of all the processors at the same time.
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

I typically work from the command line so I forget where it is but a debug profile would normally contain -O0 optimization (i.e. no optimization). For that updated code that polls for 9 to be read back from memory try making the 'j' variable volatile, regardless of whether optimizations are enabled or not that should prevent the loop from being removed. 

 

Also are you sure your both processors are actually running code? Each CPU should have it's own BSP (can't have them both sharing read/write, heap, and stack regions) so you should be able to run them independent of eachother to make sure they execute code properly up to a certain point. Once that's verified then you can download the code as a multi-download group (whatever it's called in the IDE). I normally find it easier to coordinate multiple processor downloads from the command line like this: 

 

nios2-download -i 0 -g <elf1.elf> 

nios2-download -i 1 -g -r <elf2.elf> 

nios2-terminal -i 0 

nios2-terminal -i 1 

 

The -i lets you pick which Nios II JTAG debug module/JTAG UART you are using. The -g tells nios2-download to start executing code and -r means reset the target. Normally I open one terminal window per command shell so that I can watch the output of all the processors at the same time. 

--- Quote End ---  

 

 

Yes I'm using same things: command lines 

I put j as volatile but I've always same problem, Nios2 read a false value from the shared memory
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Hi, 

 

is there any problem if each CPU has its own on-chip memory containing the code to execute 

or I should have one instruction memory shared between the two NIOS???
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Both methods are fine. I normally keep the memories seperate to simplify things but combine them is fine too.

0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

But I've always same problem, 

please tell me how to share a memory between two cpu in order to share data???
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

Depending on what I'm doing I typically either use a shared memory and a mutex or FIFOs to share data back and forth. You just connect them to the data master of each processor and both should be able to issue reads/writes to the shared data.

0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

 

--- Quote Start ---  

Depending on what I'm doing I typically either use a shared memory and a mutex or FIFOs to share data back and forth. You just connect them to the data master of each processor and both should be able to issue reads/writes to the shared data. 

--- Quote End ---  

Pl 

 

what version of qsys and NIOSII SBT are you using??
0 Kudos
Altera_Forum
Honored Contributor II
2,240 Views

I use all sorts of different versions, typically whichever is the latest is what I use. I haven't been working on Nios II projects lately so the last version was probably 12.0

0 Kudos
Reply