Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20405 Discussions

HPS2FPGA bridge on DE0-Nano-SoC (5CSEMA4U23C6N) and GHRD

Honored Contributor II



My device is DE0-Nano-SoC with GSRD and GHRD from System CD with minor changes. 


I implemented an Avalon-MM module and would like to access it throught HPS2FPGA by 128-bit bus. But I was failed with searching for any valuable examples and with trying to do it myself. 

I connected this module to both HPS2FPGA and LW_HPS2FPGA bridges. The access to LW_HPS2FPGA is well explained in the manuals hopefully and I successfully got one 32-less-significant-bits word from 4 expected. But when reading from where I expect to find the AXI data all the words are zero-filled. 


I am trying to access AXI and LWAXI in quite similar way with only difference in the offset from virtual base: 

I calculate the virtual base. The same value I am trying to use to acces bot the AXI and the light weight AXI later: 


Then I calculate the offset to my module: 

h2p_adc_addr = virtual_base + ((unsigned long) (ALT_LWFPGASLVS_OFST + AVALON_ADC_0_BASE) & (unsigned long) (HW_REGS_MASK)); //Using of lw_axi  

or for full 128 bit AXI: 

# define ALT_FPGASLVS_OFST (0xC0000000) ... h2p_adc_addr = virtual_base + ((unsigned long) (ALT_FPGASLVS_OFST + AVALON_ADC_0_BASE) & (unsigned long)(HW_REGS_MASK)); // FULL AXI  

But in the second case I get only zeros. 


Is it possible to use AXI with GHRD on DE0-Nano-SoC? 


Could you help me learn how to use normal AXI bridge instead of ridiculous LWAXI? 


I also was unsuccessfull in searching the constant for HPS2FPGA bridge offset while ALT_FPGASLVS_OFST is provided by socal/hps.h that frustrate a bit. Are all the offsets from Cyclon V address map specification provided by Alter C libraries? 


Why ALT_STM_OFST is used in the example from the System CD as a start point for virtual base? 



Thanks a lot in advance!
0 Kudos
2 Replies
Honored Contributor II

I've solved the problem! 


First of all, the AXI data is plased where it should be: at 0xC0000000 offset. The readdata width of the Avalon MM module is truncated to 32 bits so it should be 32 bits to not been truncated. The test module just output the requested address as the readdata value: 

module MY_AVALON_MEMORY(clk, resetn, readdata, address); input clk; input resetn; input address; output readdata; assign readdata = address; endmodule  

Below are the most important parts of C program to print this: 

# define ALT_FPGASLVS_OFST ( 0xC0000000 ) ... void *virtual_base; int fd; fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ); virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, ALT_FPGASLVS_OFST ); void *mem_addr; void *mem_max; uint32_t v; mem_addr = virtual_base + ( ( unsigned long )( MY_MEMORY_0_BASE )); //This two constants are taken from the header which is generated by the mem_max = virtual_base + ( ( unsigned long )( MY_MEMORY_0_END )); while (mem_addr < mem_max) { v = *((uint32_t *) mem_addr); printf("%08X\t%08X\n", (unsigned int) mem_addr, (unsigned int) v); mem_addr += sizeof(uint32_t); } close( fd );  

The result are two pretty nice columns full of data: 

72E19000 00000000 72E19004 00000001 72E19008 00000002 72E1900C 00000003 72E19010 00000004 72E19014 00000005 72E19018 00000006 72E1901C 00000007 72E19020 00000008 72E19024 00000009 72E19028 0000000A 72E1902C 0000000B 72E19030 0000000C 72E19034 0000000D 72E19038 0000000E 72E1903C 0000000F 72E19040 00000010 72E19044 00000011 72E19048 00000012 72E1904C 00000013 72E19050 00000014 72E19054 00000015 72E19058 00000016 72E1905C 00000017 72E19060 00000018 72E19064 00000019 72E19068 0000001A 72E1906C 0000001B 72E19070 0000001C 72E19074 0000001D 72E19078 0000001E 72E1907C 0000001F
0 Kudos

Hi, can you tell me please what did you put on the HW_REGS_SPAN for the 128 bits bridge? Thanks


0 Kudos