Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Chester-Gillon/cb100c103f2888b51f35404cb645b513 to your computer and use it in GitHub Desktop.

Select an option

Save Chester-Gillon/cb100c103f2888b51f35404cb645b513 to your computer and use it in GitHub Desktop.
AXI Interconnect and SmartConnect don't support address remap

Have been using AXI Interconnect and SmartConnect in Vivado block designs to map multiple different peripherals to access via PCIe, without previously finding issues.

For the U200_100G_ether_simplex_tx went to add a second CMAC block.

The AXI SmartConnect assignments in the /xdma_0/M_AXI_LITE address space were:

Master Segment Name Slave Segment Offset Range
SEG_cmac_usplus_0_Reg /cmac_usplus_0/s_axi/Reg 0x0000 8K
SEG_axi_gpio_0_Reg /axi_gpio_0/S_AXI/Reg 0x2000 8K
SEG_system_management_wiz_0_Reg /system_management_wiz_0/S_AXI_LITE/Reg 0x4000 8K
SEG_axi_quad_spi_0_Reg /axi_quad_spi_0/AXI_LITE/Reg 0x6000 8K
SEG_cmac_usplus_1_Reg /cmac_usplus_1/s_axi/Reg 0x8000 8K
SEG_cms_subsystem_0_Mem /cms_subsystem_0/s_axi_ctrl/Mem 0x40000 256K

The problem is that the cmac_usplus_1 registers were reading as all ones, while the cmac_usplus_0 registers were OK:

linux@DESKTOP-BVUMP11:~/fpga_sio/software_tests/eclipse_project/bin/release> identify_pcie_fpga_design/display_identified_pcie_fpga_designs 
Opening device 0000:31:00.0 (10ee:903f) with IOMMU group 22
Enabled bus master for 0000:31:00.0

Design U200_100G_ether_simplex_tx:
  PCI device 0000:31:00.0 rev 02 IOMMU group 22  physical slot 2-2

  DMA bridge bar 2 AXI Stream
  Channel ID  addr_alignment  len_granularity  num_address_bits
       H2C 0               1                1                64
       H2C 1               1                1                64
       C2H 0               1                1                64
  User access build timestamp : 3E32BA22 - 07/12/2025 11:40:34
  Quad SPI registers at bar 0 offset 0x6000
  SYSMON registers at bar 0 offset 0x4000
  CMAC port 0 registers at bar 0 offset 0x0
    Core mode: CAUI4
    Core version: 3.1
  CMAC port 1 registers at bar 0 offset 0x8000
    Core mode: Runtime Switchable CAUI4
    Core version: 255.255
<<snip>>

In the design added a System ILA to monitor the AXI register interfaces to cmac_usplus_0 and cmac_usplus_1 by:

  • Marking the AXI buses for debug.
  • Using the block automation to connect to the System ILA.

The capture of reads from cmac_usplus_0 (top) and cmac_usplus_1 when display_identified_pcie_fpga_designs was run: Screenshot from 2025-12-07 13-02-11

This shows:

  1. For cmac_usplus_0 the expected register values are being read and the RRESP is OKAY
  2. Whereas for cmac_usplus_1 the data returned is zero and the RRESP is SLVERR. Presumably the DMA Bridge causes all ones to be read over PCIe in response to the SLVERR.

The ARADDR passed to cmac_usplus_1 starts at offset 0x8000 which is the same offset from the host.

SmartConnect v1.0 LogiCORE IP Product Guide says:

  • SmartConnect provides no address remapping.

The previous AXI Interconnect v2.1 LogiCORE IP Product Guide says:

  • AXI Interconnect (AXI Crossbar core) provides no address remapping

I.e. with no address remapping in the interconnect, in order to registers to be read correctly required the base offset seen from the host to be a multiple of the number of address bits decoded by the peripheral.

Looking in the the block diagram:

  1. The cmac_uplus blocks have 32 bits of address on s_axi. This isn't a multiple of the base offset.
  2. The axi_quad_spi block has 7 bits of address on AXI_LITE. This is a multiple of the base offset.
  3. The system_management_wiz block has 13 bits of address on S_AXI_LITE. This is a multiple of the base offset.
  4. The axi_gpio block has 9 bits of address on S_AXI. This is a multiple of the base offset.
  5. The cms_subsystem block has 18 bits of address on s_axi_ctrl. This is a multiple of the base offset.

Following the schematic on the Synthesized Design appears to show only the lower 16 address bits being decoded. The source of the address decoding is in U200_100G_ether_simplex_tx.gen/sources_1/bd/U200_100G_ether_simplex_tx/ip/U200_100G_ether_simplex_tx_cmac_usplus_0_1/U200_100G_ether_simplex_tx_cmac_usplus_0_1/example_design/U200_100G_ether_simplex_tx_cmac_usplus_0_1_axi4_lite_reg_map.v. While the input to this module has a 32-bit address, only the bottom 16 bits are used in the actual decoding:

           //////- Write transaction
           if ( AXI_write_rise_edge) begin
              case (Bus2IP_Addr_reg[15:0])
                 'h0000 : begin
                                 GT_RESET_REG         <=  Bus2IP_Data_reg[0];
                                 IP2Bus_WrError  <=  1'b0;
                              end
                              // <snip> other valid decoded addresses
                    default : begin
                                 IP2Bus_WrError  <= 1'b1;
                              end

              endcase
           //////- Read transaction
           if ( (Bus2IP_CS_rise_edge) & (Bus2IP_RNW) ) begin
              case (Bus2IP_Addr_reg[15:0])

                  'h0000 : begin
                                 IP2Bus_Data      <=  {31'd0,GT_RESET_REG};
                                 IP2Bus_RdError   <=  1'b0;
                               end 
                              // <snip> other valid decoded addresses
                     default : begin
                                 IP2Bus_Data     <= 'd0;
                                 IP2Bus_RdError  <= 1'b1;
                               end

              endcase

Which shows invalid register addresses are signalled with a IP2Bus_WrError or IP2Bus_RdError.

Changed the base address of cmac_usplus_1 from 0x8000 to 0x10000 so that the offset is a multiple of the number of decoded address bits. That allowed the cmac_usplus_1 registers to be accessed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment