Forum Discussion
Altera_Forum
Honored Contributor
13 years agoProblem with IORD and IOWR instructions
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?18 Replies
- Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
--- 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) - Altera_Forum
Honored Contributor
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??
- Altera_Forum
Honored Contributor
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? - Altera_Forum
Honored Contributor
--- 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 - Altera_Forum
Honored Contributor
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?? - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
--- 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?? - Altera_Forum
Honored Contributor
--- 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