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:

This shows:
- For
cmac_usplus_0the expected register values are being read and theRRESPisOKAY - Whereas for
cmac_usplus_1the data returned is zero and theRRESPisSLVERR. Presumably the DMA Bridge causes all ones to be read over PCIe in response to theSLVERR.
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:
- The
cmac_uplusblocks have 32 bits of address ons_axi. This isn't a multiple of the base offset. - The
axi_quad_spiblock has 7 bits of address onAXI_LITE. This is a multiple of the base offset. - The
system_management_wizblock has 13 bits of address onS_AXI_LITE. This is a multiple of the base offset. - The
axi_gpioblock has 9 bits of address onS_AXI. This is a multiple of the base offset. - The
cms_subsystemblock has 18 bits of address ons_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
endcaseWhich 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.