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

Lightweight HPS to FPGA Bridge register accessses not working

Honored Contributor II



I created a System in Qsys with a slave-template from Altera and offset it to base 0x10000 relative to lightweight H2F bridge. (image1) 


In Quartus I connected the SoC-System outputs of the slave-template. (image2) I got 2 r/w registers configured in the slave-template wizard in qsys. 

Since the slave-template gives me the std_logic_vectors for in and outbound data, i just inserted a loopback and made reg0 output what was input into reg0. the same for the second register. 


Now as I understood, the lightweight AXI is 32bit width. Is the addressing byte- or wordaddressing? 


In my baremetal program I do the following first: 

# define LWHPS2FPGA_BRIDGE_BASE 0xFF200000 //lightweight h2f bridge base# define test_out_base 0x10000 //offset of the qsys avalon slave component (slave-template) 



volatile unsigned int *reg0 = (volatile unsigned int *)LWHPS2FPGA_BRIDGE_BASE + test_out_base; //first register 

volatile unsigned int *reg1 = (volatile unsigned int *)LWHPS2FPGA_BRIDGE_BASE + test_out_base+2; //second register when word-addressing 

volatile unsigned int *reg2 = (volatile unsigned int *)LWHPS2FPGA_BRIDGE_BASE + test_out_base+4; //second register when byte-addressing 


I always read 32bit as I am using unsigned int*, do I have to read 8bit instead by using char*? I tried it, but it did not work, too. 

Then I'm writing/reading regs like: 


getc(); //wait for button 

*reg0 = 0x12345678; 

puts("put 0x12345678 to reg0 ... read now?\n"); 


printf("reg0: %x\n",*reg0); 


I did the same for *reg1 and *reg2. but no matter what I write into the registers, whenever I read them, they are 0. 


What am I missing/messing up here? 


Thanks for every hint!
0 Kudos
3 Replies
Honored Contributor II

okay, when I use the AXI h2f_master instead of the lightweight AXI, all is working. the only thing i changed is: hook up the slave template component in qsys to h2f_master instead of lw_h2f_master and for the addresses in the baremetal app I used 0xC0000000 instead of 0xFF200000 as the bridge base. since I'm booting from FPGA, I know that h2f full bridge is configured correct, cause it's loading the preloader from on-chip-memory. 


So the question is: do I have to take the h2f lightweight bridge out of reset or configure it somehow? I thought qsys is handing this config info to the preloader generation process when I setup the lightweight bridge in the HPS component in qsys?
0 Kudos
Honored Contributor II

ok, forget my last post. it's still not working. the values are saved, but they are even saved when i remove my loopback for the slave template in/out std_logic_vectors. so i probably write to the on-chip-memory here which begins at 0xC0000000. but WHY? I am writing to volatile unsigned int *reg0 = H2F_BRIDGE + test_out_base; where# define H2F_BRIDGE 0xC0000000 and# define test_out_base 0x10000. this should be outside the address range of the on-chip-memory and 0x10000 is the offset of the slave template qsys component. 


I don't get any further. this should be one of the simplest tasks to implement, I really would like to start developing, but I cannot seem to get beyond this. Can anyone help me please? I know I am missing something obvious.
0 Kudos
Honored Contributor II

okay, solved the problem, either nobody is reading my threads or nobody has experience with pointers or I'm just a noob, everybody is laughing at. 

I don't care, maybe someone can make a use of this: 


volatile unsigned int *reg0 = (volatile unsigned int *)LWHPS2FPGA_BRIDGE_BASE + test_out_base; 


this is equivalent to reg0 = (volatile unsigned int *)( LWHPS2FPGA_BRIDGE_BASE + (test_out_base * 4) ); 


because increasing an int pointer adds + 4 (since int are (often) 4byte type) to the stored address. 


all I had to do was add brackets to make the addition happen before casting one summand: 


volatile unsigned int *reg0 = (volatile unsigned int *)(LWHPS2FPGA_BRIDGE_BASE + test_out_base); 


thank you larso for helping me out! 

you're welcome larso! 

happy xmas, hanuka, kwanzaa, whateveryoulike to everyone.
0 Kudos