cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
238 Views
Registered: ‎06-13-2019

AXI Memory Mapped to PCI Express as Root Port, automatic AXI:BAR Configuration

Jump to solution

Hello,

In my basic understanding of PCIe, the PCIe Endpoint device is telling the Root Complex (or the processing system) which memory ranges/size it is requesting (BAR Configuration).

Is the "AXI Memory Mapped to PCI Express IP" configured as a Root Port supporting this functionality or do I have to know the requested configuration of the Endpoint beforehand? What is the role of the AXI:BARS in this context?

As far as I understand the concept, the AXI:BARS are used for reading/writing from/to the Endpoint device controlled by the host, including some AXI to PCIe address translation. If the Endpoint is requesting 2 BARs and I only enabled one BAR in the AXI:BARS tab, then this device will not work? Are the Endpoint BARs "communicated" to the host the same as the BARs configured in the AXI:BARS tab?

Can I connect the IP in Root Port mode to a PCIe switch?

Thank you very much in advance!

Kind regards
Stefan

 

0 Kudos
1 Solution

Accepted Solutions
Xilinx Employee
Xilinx Employee
138 Views
Registered: ‎12-10-2013

Re: AXI Memory Mapped to PCI Express as Root Port, automatic AXI:BAR Configuration

Jump to solution

Hi @stefanglaser86 

There are a lot of questions there - so let me try to break it down from the endpoint side, since that seems to be your focus.

The AXI Bridge has 2 sets of BARs, as you have seen.  The PCIe BARs (which get enumerated by the Root Complex) and the AXI BARs.   I will state upfront that this core is much easier to design with in IPI then RTL.

Requests to AXI Bridge endpoint from Root Port

The PCIe BARs are specifically for incoming request from the Root.  So the Root sends a MemRd, MemWr, then that goes to the PCIe BAR (which you set the size and aperature in the GUI).   There is another box on that tab for translation.  This says "For whatever the root assigns the base address of PCIe to, I want the AXI address on the M_AXI interface to be x".   It is a Base to Base assignment.   Then you would connect that M_AXI port to some AXI Slave (like BRAM or DDR), or multiple AXI slaves.   So if you leave this value zero, and an incoming PCIe Read Request comes in at the PCIE_BAR address + 0x1000, then the M_AXI_ARADDR will reflect 0x1000.   Just know that whatever translation address you pick must be aligned to the *size* of your PCIe Bar.  So if you selected a 512MB PCIe BAR, then your PCIEBAR2AXIBAR translation address must be 512MB aligned.

You can enable 2 BARs here, just assign them to different translation addresses in AXI address space, then connect to 2 or more AXI slave via an AXI Interconnect (and address manager).

Note from the above - all of this is completely independent of what is going on on the AXI:BAR tab, and is only for incoming requests.

Request to Root Port from AXI Bridge Endpoint

Outgoing requests is where your AXI:BAR tab comes into play (along with your S_AXI interface on the user side of the core).   Depending on if you are in RTL flow or IPI flow, this tab looks a little different.  In RTL flow, you assign the Low and High address in the tab, and the translation address (from AXI to PCIe); in the IPI flow, you just select the translation address, and the Low and High are taken from your Address Manager selections. 

This idea here is that you have some AXI Master in your design (like a Microblaze, or JTAG to AXI) that needs to read/write some data in host memory.  So you set your low and high AXI addresses (to somewhere different from where your RP to EP transactions are going).  Note that these also have to be aligned to you AXI BAR aperature.  Then, you set the translation (AXIBAR2PCIEBAR) address.  You are saying, I know my AXI base (low) address for each of these BARs, and I want it to go to PCIe at the address in this box.  Again, I use the example of an AXI BAR that is 0x7000_0000 to 0x7FFF_FFFF, and I put 0x8000_0000 in that translation box.  An AXI request made on the S_AXI interface at S_AXI_ARADDR of 0x7001_0000 will go on PCIe as a MemRd at 0x8001_0000.

Note again, all of the above is independent of the PCIe BAR tab. 

The follow on question to this is "what if I don't know where I will be allowed to send requests in host memory?".   You can change that AXIBAR2PCIEBAR translation (the upstream request direction) via Bridge Registers via the S_AXIL interface.  So at the AXI address shown in the register map (I believe 0x208 for the first AXI BAR) - you can change that 0x8000_0000 from above to a different value.   How you communicate from your host driver that did the memory allocation to the OS down to that S_AXIL interface is up to you. 

Suggestions

I highly recommend mapping out your addressing ahead of time on an excel spreadsheet or similar.  I put my PCIe address blocks on one side, and my AXI address blocks on the other representing the various AXI slaves and masters I need to have connected, and just figure out the translation addresses visually for each direction.   It is important to remember that all addresses have to be aligned based on aperture, and that the two directions are basically independent - incoming requests on M_AXI, outgoing on S_AXI.

Root Port

The other parts of your questions were around the Root Port of the AXI Bridge.  It behaves essentially the same as the above - but the "heavier use" directions are reversed.  A Root Port will connect to a downstream endpoint (via a PCIe switch if that is your architecture), and will send requests via the S_AXI interface, and receive requests from the endpoint on the M_AXI interface.  There are more nuances in setting up the Root Port for interrupt decode, etc, and you will need to create a basic driver or code to enumerate the downstream.  We do provide an example design with "CGATOR" (configurator) code that does the bare bones of the endpoint enumeratione. 

 

Hope that helps!  You can also reference Answer 56616 for visuals on the above.

https://www.xilinx.com/support/answers/56616.html

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

1 Reply
Xilinx Employee
Xilinx Employee
139 Views
Registered: ‎12-10-2013

Re: AXI Memory Mapped to PCI Express as Root Port, automatic AXI:BAR Configuration

Jump to solution

Hi @stefanglaser86 

There are a lot of questions there - so let me try to break it down from the endpoint side, since that seems to be your focus.

The AXI Bridge has 2 sets of BARs, as you have seen.  The PCIe BARs (which get enumerated by the Root Complex) and the AXI BARs.   I will state upfront that this core is much easier to design with in IPI then RTL.

Requests to AXI Bridge endpoint from Root Port

The PCIe BARs are specifically for incoming request from the Root.  So the Root sends a MemRd, MemWr, then that goes to the PCIe BAR (which you set the size and aperature in the GUI).   There is another box on that tab for translation.  This says "For whatever the root assigns the base address of PCIe to, I want the AXI address on the M_AXI interface to be x".   It is a Base to Base assignment.   Then you would connect that M_AXI port to some AXI Slave (like BRAM or DDR), or multiple AXI slaves.   So if you leave this value zero, and an incoming PCIe Read Request comes in at the PCIE_BAR address + 0x1000, then the M_AXI_ARADDR will reflect 0x1000.   Just know that whatever translation address you pick must be aligned to the *size* of your PCIe Bar.  So if you selected a 512MB PCIe BAR, then your PCIEBAR2AXIBAR translation address must be 512MB aligned.

You can enable 2 BARs here, just assign them to different translation addresses in AXI address space, then connect to 2 or more AXI slave via an AXI Interconnect (and address manager).

Note from the above - all of this is completely independent of what is going on on the AXI:BAR tab, and is only for incoming requests.

Request to Root Port from AXI Bridge Endpoint

Outgoing requests is where your AXI:BAR tab comes into play (along with your S_AXI interface on the user side of the core).   Depending on if you are in RTL flow or IPI flow, this tab looks a little different.  In RTL flow, you assign the Low and High address in the tab, and the translation address (from AXI to PCIe); in the IPI flow, you just select the translation address, and the Low and High are taken from your Address Manager selections. 

This idea here is that you have some AXI Master in your design (like a Microblaze, or JTAG to AXI) that needs to read/write some data in host memory.  So you set your low and high AXI addresses (to somewhere different from where your RP to EP transactions are going).  Note that these also have to be aligned to you AXI BAR aperature.  Then, you set the translation (AXIBAR2PCIEBAR) address.  You are saying, I know my AXI base (low) address for each of these BARs, and I want it to go to PCIe at the address in this box.  Again, I use the example of an AXI BAR that is 0x7000_0000 to 0x7FFF_FFFF, and I put 0x8000_0000 in that translation box.  An AXI request made on the S_AXI interface at S_AXI_ARADDR of 0x7001_0000 will go on PCIe as a MemRd at 0x8001_0000.

Note again, all of the above is independent of the PCIe BAR tab. 

The follow on question to this is "what if I don't know where I will be allowed to send requests in host memory?".   You can change that AXIBAR2PCIEBAR translation (the upstream request direction) via Bridge Registers via the S_AXIL interface.  So at the AXI address shown in the register map (I believe 0x208 for the first AXI BAR) - you can change that 0x8000_0000 from above to a different value.   How you communicate from your host driver that did the memory allocation to the OS down to that S_AXIL interface is up to you. 

Suggestions

I highly recommend mapping out your addressing ahead of time on an excel spreadsheet or similar.  I put my PCIe address blocks on one side, and my AXI address blocks on the other representing the various AXI slaves and masters I need to have connected, and just figure out the translation addresses visually for each direction.   It is important to remember that all addresses have to be aligned based on aperture, and that the two directions are basically independent - incoming requests on M_AXI, outgoing on S_AXI.

Root Port

The other parts of your questions were around the Root Port of the AXI Bridge.  It behaves essentially the same as the above - but the "heavier use" directions are reversed.  A Root Port will connect to a downstream endpoint (via a PCIe switch if that is your architecture), and will send requests via the S_AXI interface, and receive requests from the endpoint on the M_AXI interface.  There are more nuances in setting up the Root Port for interrupt decode, etc, and you will need to create a basic driver or code to enumerate the downstream.  We do provide an example design with "CGATOR" (configurator) code that does the bare bones of the endpoint enumeratione. 

 

Hope that helps!  You can also reference Answer 56616 for visuals on the above.

https://www.xilinx.com/support/answers/56616.html

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post