This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PCIe Inbound transfer settings

Hi all,

we are having troubles with the PCIe inbound transfer from the DMA of an Artix7 FPGA (EP) to the C6657 DSP (RC). The DSP has the RC role and it can correctly set-up the FPGA registers (e.g. we can successfully control a GPIO with an LED on the FPGA EVB). This means the outbound transfer is correctly working and we are using this to initiate a DMA transfer (with the FPGA DMA IP) from the FPGA input stream to the FPGA PCIe interface. The FPGA PCIe IP has been configured to translate the outgoing addresses with the base address 0x60000000 and it has also been configured to have the PCIe bus mastership. On the DSP side, the BAR1 has been activated, BAR1 mask has been configured for 128 MB memory range, BAR1 base address is 0x60000000 and the offset address (the translation) is 0x90000000 (which lands in the DSP DDR3 - there are 512 MB DDR3 memory in the DSP module) and the inbound memory region 0 is using the BAR1. Inbound address translation has also been activated. Enumeration has been done and as I said, we can correctly write/read data to/from the FPGA. However we are not able to see any data getting into the DSP DDR3 memory when the transfer is initiated by the EP, i.e. the DMA into the FPGA.

Is there any specific configuration (power domain, clock, memory bus mastership, etc.) we are probably missing for having the bus working also in that direction? 

Thanks,

Luca

  • Hi,

    Which boot mode you using on DSP side Boot?

    Have you initialized the DDR memory on DSP side? Please share your EP and RC all BAR configurations.

    Take a look at below PCI Express (PCIe) Resource Wiki:

    Thanks,

  • Hi GD,

    We're currently using a third party DSP module with the C6657. There is a Flash memory in the module and the DSP is booting from there. The DDR3 memory is initialized by the bootloader. Anyway, even if I change the destination address to be in the L2RAM, the issue is still the same, no inbound data coming from the PCIe transaction.

     

    Here is the DSP PCIe Inbound configuration:

     

    baseAppRegs->CMD_STATUS |= (1 << CSL_PCIESS_APP_CMD_STATUS_DBI_CS2_SHIFT);
    while(~baseAppRegs->CMD_STATUS & (1 << CSL_PCIESS_APP_CMD_STATUS_DBI_CS2_SHIFT));

    baseCfgRcRegs->BAR[1] = 1;
    baseCfgRcRegs->BAR[1] = 0x07FFFFFF;


    baseAppRegs->CMD_STATUS &= ~(1 << CSL_PCIESS_APP_CMD_STATUS_DBI_CS2_SHIFT);
    while(baseAppRegs->CMD_STATUS & (1 << CSL_PCIESS_APP_CMD_STATUS_DBI_CS2_SHIFT));

    baseCfgRcRegs->BAR[1] = 0x60000000 |

                           (0 << CSL_PCIE_CFG_SPACE_ROOTCOMPLEX_BAR_PREFETCHABLE_SHIFT)  |

                           (0 << CSL_PCIE_CFG_SPACE_ROOTCOMPLEX_BAR_TYPE_SHIFT)          |

                           (0 << CSL_PCIE_CFG_SPACE_ROOTCOMPLEX_BAR_MEMORY_SPACE_SHIFT);

    baseAppRegs->INBOUND_TRANSLATION[0].IB_BAR = 1;

    baseAppRegs->INBOUND_TRANSLATION[0].IB_START_HI = 0;

    baseAppRegs->INBOUND_TRANSLATION[0].IB_START_LO = 0x60000000;

    baseAppRegs->INBOUND_TRANSLATION[0].IB_OFFSET = 0x90000000;

    baseAppRegs->CMD_STATUS |= (1 << CSL_PCIESS_APP_CMD_STATUS_IB_XLT_EN_SHIFT);

     

    On the FPGA side, no configuration is made for the Outbound traffic from the DSP since the Outbound translation addresses are hardcoded in the FPGA firmware (the Oubound offset address is 0x60000000). The only thing the DSP does while enumerating the FPGA and setting up its Inbound translation registers, is enabling the mastership of the bus.

     

    Luca

  • Luca,

    I would suggest to plug ChipScope onto your FPGA design and make sure the transfer is actually activated. You can monitor transaction interface of the PCIe IP Core. on receiver side you should notice PIO activity to trigger DMA in IP. It should be followed by larger DMA packets from FPGA towards DSP. Particularly, you may look inside those transaction layer packets. The third DWORD would have destination address, because it looks like FPGA IP is to make posted writes. If you see that activity, then the problem is with address translation, otherwise - check FPGA side. You should see addresses with 0x60000000 base in the third DWORD of the packet.

    Another point is how do you actually look at your received data. Because the transfer does not involve the CPU, its cache controller has no idea the data in the target region may have changed. So probably you may need to invalidate caches for the target region before reading them.

    In our design we are using C6670 which has no valid target at address 0x9000_0000, so we are using that address as address in PCIe address space. So the relevant excerpt from my code is

    ibCfg.ibBar         = 1; // Match BAR that was configured above
    ibCfg.ibStartAddrLo = 0x90000000;
    ibCfg.ibStartAddrHi = 0;
    ibCfg.ibOffsetAddr  = target buffer global address;
    ibCfg.region        = 0;
    
    pcie_ib_trans_cfg(handle, &ibCfg);
    
    barCfg.idx      = 1;
    barCfg.location = pcie_LOCATION_LOCAL;
    barCfg.mode     = pcie_RC_MODE;
    barCfg.base     = 0x90000000;
    barCfg.prefetch = pcie_BAR_NON_PREF;
    barCfg.type     = pcie_BAR_TYPE32;
    barCfg.memSpace = pcie_BAR_MEM_MEM;
    
    Pcie_cfgBar(handle, &barCfg);

    We use PCIe LLD here, though I already regret about that, but anyway you may see that important thing is to match BAR's base with translation region, which you seems to be doing right.

  • Hi rrlagic,

    Thanks for your suggestions.

    We used the ChipScope and we found out our configuration wasn't working as we thougth. Since our FPGA PCIe memory space is 1GB, the FPGA BAR mask is 0x3FFFFFFF. This means the internal address is masked so that only its 30 LSBs are kept and the two remaining MSBs are taken from the BAR offset. Our problem was that we put 0x60000000 in the BAR offset, and we expected the translated address was 0x6xxxxxxx. But since the only 2 MSB are used for the translation, the output translated address was 0x4xxxxxxx instead.

    Hope this will be helpful for somebody else.

    Thanks,
    Luca