Intel® High Level Design
Support for Intel® High Level Synthesis Compiler, DSP Builder, OneAPI for Intel® FPGAs, Intel® FPGA SDK for OpenCL™
684 Discussions

Memory Conflicts in onchip ram

ggxnd
Beginner
1,962 Views

I am using IOWR_32DIRECT to write contents in the on-chip ram and using IORD_32DIRECT to read from the same address where I performed write operation. Upto few memory location the write and read data matches. Issue arises when I perform those operation in a loop till I fill the complete on-chip ram addresses (say 2MB), it results in some memory conflicts. Either write data and read data is not matching or the compiler is not processing properly resulting in some weird print character.  Does it depends on number of times IOWR_32DIRECT  and IORD_32DIRECT execution? On what part of hardware configuration does it depends on? What is the minimum program area needed for such functionality?

Thanks in Advance!

0 Kudos
11 Replies
ShengN_Intel
Employee
1,906 Views

Hi,

 

I had created a simple design that consists of clock, OCR, Nios II, jtag uart and data in/out component. The OCR address is range from 0x40000 (Base) to 0x657ff (End). The corresponding decimal for 0x40000 (Base) and 0x657ff (End) are 262144 and 415743 respectively.

I had created a code which loops to IOWR_32DIRECT and IORD_32DIRECT the data for each OCR address. The first data is 262144 which being incremented by 1 for each loop until 415743. In the terminal, I'm getting decimal 415743 for address 0x657ff means the data are matching with each address respectively. Attached the project file below for your reference.

Code:

# include <stdio.h>

# include "system.h"

# include "io.h"

 

#define BASE_ADDRESS ONCHIP_MEM_BASE

#define END_ADDRESS 0x657FF

 

int main() {

int i = 262144;

unsigned int addr;

  for (addr = BASE_ADDRESS; addr <= END_ADDRESS; addr++) {

  char addr_str[11]; // Assumes 32-bit address

  snprintf(addr_str, sizeof(addr_str), "0x%05x", addr);

    IOWR_32DIRECT(addr_str, 1, i);

    printf("Address: 0x%x, Value: %d\n", addr, IORD_32DIRECT(addr_str, 1));

    i++;

  }

  return 0;

}

Terminal screenshot:

Screenshot 2023-09-20 213939.png

Not sure your case is because of processor speed or not. What will happen if you add small delay to the loop?

 

Thanks,

Best Regards,

Sheng

p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 4/5 survey.

 

 

0 Kudos
ggxnd
Beginner
1,890 Views

Hi,
Thank you for your reply.  I will have a look into the solution that you  provided. I have a doubt.
The following is how I try to perform write and read.

for (addr = 0;  addr <= END_ADDRESS; addr += 4) {

 IOWR_32DIRECT(BASE_ADDRESS, addr, i);

}

for (addr = 0;  addr <= END_ADDRESS; addr += 4) {

 value = IORD_32DIRECT(BASE_ADDRESS, addr);
printf("Address: 0x%x, Value: %d\n", addr, value);

}

What is the key difference between the your code and the above one. Why is it failing to provide same result here.? Can you provide any insight / idea on this?

0 Kudos
ggxnd
Beginner
1,891 Views

 

    

0 Kudos
ShengN_Intel
Employee
1,866 Views

Hi,


The code provided by me I'm just increasing the address part (addr_str) for each loop. While keeping the address offset at constant 1.

Compared to yours, you're increasing the address offset (addr) part instead. Why not you just keep the address offset constant and increase the address part for each loop any difference?


Thanks,

Best Regards,

Sheng


0 Kudos
ggxnd
Beginner
1,798 Views

Hi,
The address part (addr_str) doesn't seem to be increasing.
How the address translation done here - IOWR_32DIRECT(addr_str, 1, i); and on what address the data 'i'  is write into?
If I want to read the value from a particular address(from the above mentioned range - BASE_ADDR to END_ADDR) outside this loop , how it can be done? 
When I try to read it outside the loop, the same write value is not obtained. so my doubt is how address translation in done in IOWR_32DIRECT ?
Also IOWR_32DIRECT macro is to perform a memory-mapped I/O write operation , we can directly pass numerical value. What is the need to pass formatted string in that?

Thanks in Advance!

0 Kudos
ShengN_Intel
Employee
1,767 Views

Hi,

 

There's some mistake in the previous code posted. Done modified as below:

int main() {

int i = 262144;

unsigned int addr;

unsigned int result;

 

 for (addr = BASE_ADDRESS; addr <= 0x40019; addr+=4) {

  IOWR_32DIRECT(addr, 0x4, i);

  i++;

 }

 for (result = BASE_ADDRESS; result <= 0x40019; result++ ) {

 printf("Address: 0x%x, Value: %d\n", result, IORD_32DIRECT(result, 0x4));

 }

 printf("Address: 0x40016, Value: %d\n", IORD_32DIRECT(0x40016, 0x4));

 printf("Address: 0x40007, Value: %d\n", IORD_32DIRECT(0x40007, 0x4));

 

 return 0;

}

 

Terminal screenshot below:

Screenshot 2023-09-26 120235.png

Address part is increasing correctly and can read value outside the loop correctly. Ya, you're right can pass directly the numerical value.

 

You can checkout this link https://fys4220.github.io/part-exercises/exercises_memory_mapped_sw.html on byte-oriented offset for IOWR_32DIRECT and IORD_32DIRECT

 

Thanks,

Best Regards,

Sheng

 

 

 

0 Kudos
ggxnd
Beginner
1,761 Views

Hi, 
Thanks.
My question is does the same works for 2MB address location of OCR. What if the end address is increased so that it writes 2MB location? 

0 Kudos
ShengN_Intel
Employee
1,738 Views

Hi,


I'm not able to complete in one run as well. Because some of the address locations require different data length or format and they're all mixed.

May be try to read first those address locations which got memory conflicts to know the data format and try to run in separate trial.

Btw, possible to provide your code for testing out on my platform?


Thanks,

Best Regards,

sheng


0 Kudos
ggxnd
Beginner
1,632 Views

Hi,
Yes. Is there any other way to address this issue? why the write data is not matching with the read data? Why the read function fails to read the write data? or Is there any memory limitations in onchip ram?

Code is similar to the one you modified.

int main() {

int i = 262144;

unsigned int addr;

unsigned int result;

 

 for (addr =0; addr <=0x1FFFFF ; addr+=4) {

  IOWR_32DIRECT(BASE_ADDRESS, addr, i);

  i++;

 }

 for (addr = 0; addr <= 0x1FFFFF; addr+=4 ) {

 printf("Address: 0x%x, Value: %d\n", BASE_ADDRESS+ addr, IORD_32DIRECT(BASE_ADDRESS, addr));

 }

 

 

 return 0;

}
Thanks.



0 Kudos
ShengN_Intel
Employee
1,464 Views

Hi,


Yes. There're some memory limitations as some of the address locations are not writeable. I would suggest you using this method to verify the matching of the write and read data:

int main() {

IOWR_32DIRECT(ONCHIP_MEM_BASE, 0x1FFFFF, "<string>");

printf("%s\n", IORD_32DIRECT(ONCHIP_MEM_BASE, 0x1FFFFF));


return 0;

}


Thanks,

Best Regards,

Sheng




0 Kudos
ShengN_Intel
Employee
1,452 Views

Another method below can be used as well:

int main() {

IOWR(ONCHIP_MEM_BASE, 0x1FFFFF, "<string>");

alt_printf("%s\n", IORD(ONCHIP_MEM_BASE, 0x1FFFFF));

return 0;

}


0 Kudos
Reply