1. 概述 | Holoscan Sensor Bridge 文档
NVIDIA Holoscan Sensor Bridge FPGA IP 与 Holoscan 软件配套使用,为最终用户提供一种与传感器无关的数据到以太网主机平台。该 IP 核简化了 FPGA 设计并加速开发进程,可按需扩展和配置,以适应各种传感器到主机的应用场景。
Holoscan Sensor Bridge IP 的主要功能
- 将传感器 AXI-Stream 数据封装为以太网 UDP AXI-Stream 数据,供主机处理。
- 执行 BOOTP、ICMP 以及 NVIDIA 定义的以太网控制总线(ECB)网络协议。
- 传输枚举包和控制事件包,用于预定义条件触发。
- 控制外设接口(如 SPI/I2C/GPIO),用于配置传感器及其他板载组件。
下图展示了 FPGA 中 Holoscan Sensor Bridge IP 的框图。其中,**传感器接口(Sensor Interface)和主机(以太网)接口(Host Interface)**模块为 FPGA 厂商特定的逻辑。

图 1. FPGA 中的 Holoscan Sensor Bridge IP
Holoscan Sensor Bridge IP 架构
Holoscan Sensor Bridge IP 的架构如下图所示。

图 2. Holoscan Sensor Bridge IP 架构
Holoscan Sensor Bridge IP 中的数据桥接分为两个主要平面:
- 数据平面(Dataplane):负责传感器数据的传输,将传感器数据打包为 UDP 数据包。
- 控制平面(Controlplane):负责主机控制相关的数据传输。控制平面可以接收并解码来自主机的 UDP 数据包以访问寄存器,或传输 Holoscan Sensor Bridge IP 支持的特定网络协议。
资源利用率
Holoscan Sensor Bridge IP 的资源利用率可应要求提供。
2. 端口描述 | Holoscan Sensor Bridge 文档
Holoscan Sensor Bridge IP 的端口描述将在以下各节中介绍。有关 “HOLOLINK_def.svh” 中定义的宏的更多信息,请参阅 宏定义 章节。
全局复位
表 1 全局复位端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_sys_rst | 输入 | 全局异步高电平有效复位 |
用户寄存器端口
表 2 用户寄存器时钟与复位端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_apb_clk | 输入 | APB 时钟。必须大于 20MHz。 |
o_apb_rst | 输出 | APB 同步高电平有效复位 |
表 3 用户寄存器 APB 端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_apb_pready [N-1:0]¹ | 输入 | APB 就绪 |
[31:0] i_apb_prdata[N-1:0]¹ | 输入 | APB 读数据 |
i_apb_pserr[N-1:0]¹ | 输入 | APB 完成者错误 |
o_apb_psel[N-1:0]¹ | 输出 | APB 选择 |
o_apb_penable | 输出 | APB 使能 |
o_apb_paddr[31:0] | 输出 | APB 地址 |
o_apb_pwdata[31:0] | 输出 | APB 写数据 |
o_apb_pwrite | 输出 | APB 写使能 |
¹ N = REG_INST
表 4 外部枚举端口
以下端口仅在 “HOLOLINK_def.svh” 中未定义 ENUM_EEPROM 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
[47:0] i_mac_addr[N-1:0]¹ | 输入 | 每个以太网接口的 MAC 地址。 |
i_board_sn[55:0] | 输入 | 板卡序列号。 |
i_enum_vld | 输入 | 枚举有效。当 i_mac_addr 和 i_board_sn 设置完成后,置位并保持为 1。 |
¹ N = HOST_IF_INST
表 5 用户寄存器系统初始化端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
o_init_done | 输出 | 系统初始化完成。请参阅 系统初始化 章节。 |
传感器接口端口
表 6 传感器 RX 接口端口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 SENSOR_RX_IF_INST 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_sif_rx_clk[N-1:0]¹ | 输入 | 传感器 RX 接口时钟。 |
o_sif_rx_rst[N-1:0]¹ | 输出 | 传感器 RX 接口同步高电平有效复位。 |
i_sif_axis_tvalid[N-1:0]¹ | 输入 | 传感器 RX AXI-Stream 有效。 |
i_sif_axis_tlast[N-1:0]¹ | 输入 | 传感器 RX AXI-Stream 末尾。 |
[W-1:0] i_sif_axis_tdata[N-1:0]¹ | 输入 | 传感器 RX AXI-Stream 数据。 |
[X-1:0] i_sif_axis_tkeep[N-1:0]¹ | 输入 | 传感器 RX AXI-Stream 字节保持。当前不支持。详见 传感器 RX 章节。 |
[Y-1:0] i_sif_axis_tuser[N-1:0]¹ | 输入 | 传感器 RX AXI-Stream 用户数据。 |
o_sif_axis_tready[N-1:0]¹ | 输出 | 传感器 RX AXI-Stream 就绪。 |
¹ N = SENSOR_RX_IF_INST, W = DATAPATH_WIDTH, X = DATAKEEP_WIDTH, Y = DATAUSER_WIDTH
表 7 传感器 TX 接口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 SENSOR_TX_IF_INST 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_sif_tx_clk[N-1:0]¹ | 输入 | 传感器 TX 接口时钟。 |
o_sif_tx_rst[N-1:0]¹ | 输出 | 传感器 TX 接口同步高电平有效复位。 |
o_sif_axis_tvalid[N-1:0]¹ | 输出 | 待定义(TBD) |
o_sif_axis_tlast[N-1:0]¹ | 输出 | 待定义(TBD) |
[W-1:0] o_sif_axis_tdata[N-1:0]¹ | 输出 | 待定义(TBD) |
[X-1:0] o_sif_axis_tkeep[N-1:0]¹ | 输出 | 待定义(TBD) |
[Y-1:0] o_sif_axis_tuser[N-1:0]¹ | 输出 | 待定义(TBD) |
i_sif_axis_tready[N-1:0]¹ | 输入 | 待定义(TBD) |
¹ N = SENSOR_TX_IF_INST, W = DATAPATH_WIDTH, X = DATAKEEP_WIDTH, Y = DATAUSER_WIDTH
表 8 传感器事件端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_sif_event [15:0] | 输入 | 传感器接口事件。异步信号。详见 传感器 RX 章节。 |
主机接口端口
表 9 主机接口时钟与复位端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_hif_clk | 输入 | 156.25MHz 主机接口时钟。详见 时钟 章节。 |
o_hif_rst | 输出 | 主机接口同步高电平有效复位。 |
表 10 主机 RX 接口端口
将主机 RX AXI-Stream 端口直接连接到以太网 MAC RX AXI-Stream 端口。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_hif_axis_tvalid[N-1:0]¹ | 输入 | AXI-Stream 有效 |
i_hif_axis_tlast[N-1:0]¹ | 输入 | AXI-Stream 末尾 |
[W-1:0] i_hif_axis_tdata[N-1:0]¹ | 输入 | AXI-Stream 数据 |
[X-1:0] i_hif_axis_tkeep[N-1:0]¹ | 输入 | AXI-Stream 字节保持 |
[Y-1:0] i_hif_axis_tuser[N-1:0]¹ | 输入 | AXI-Stream 用户数据 |
o_hif_axis_tready[N-1:0]¹ | 输出 | AXI-Stream 就绪 |
¹ N = HOST_IF_INST, W = DATAPATH_WIDTH, X = DATAKEEP_WIDTH, Y = DATAUSER_WIDTH
表 11 主机 TX 接口端口
将主机 TX AXI-Stream 端口直接连接到以太网 MAC TX AXI-Stream 端口。
| 信号名称 | 方向 | 描述 |
|---|---|---|
o_hif_axis_tvalid[N-1:0]¹ | 输出 | AXI-Stream 有效 |
o_hif_axis_tlast[N-1:0]¹ | 输出 | AXI-Stream 末尾 |
[W-1:0] o_hif_axis_tdata[N-1:0]¹ | 输出 | AXI-Stream 数据 |
[X-1:0] o_hif_axis_tkeep[N-1:0]¹ | 输出 | AXI-Stream 字节保持 |
[Y-1:0] o_hif_axis_tuser[N-1:0]¹ | 输出 | AXI-Stream 用户数据 |
i_hif_axis_tready[N-1:0]¹ | 输入 | AXI-Stream 就绪 |
¹ N = HOST_IF_INST, W = DATAPATH_WIDTH, X = DATAKEEP_WIDTH, Y = DATAUSER_WIDTH
外设接口端口
表 12 SPI 端口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 SPI_INST 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
o_spi_csn[N-1:0]¹ | 输出 | 片选(低电平有效) |
o_spi_sck[N-1:0]¹ | 输出 | SPI 时钟 |
o_spi_oen[N-1:0]¹ | 输出 | 输出使能 |
[3:0] o_spi_sdio[N-1:0]¹ | 输出 | SDIO 输出 |
[3:0] i_spi_sdio[N-1:0]¹ | 输入 | SDIO 输入 |
¹ N = SPI_INST
表 13 I2C 端口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 I2C_INST 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_i2c_scl[N-1:0]¹ | 输入 | I2C 时钟 |
i_i2c_sda[N-1:0]¹ | 输入 | I2C 数据 |
o_i2c_scl_en[N-1:0]¹ | 输出 | I2C 时钟输出使能 |
o_i2c_sda_en[N-1:0]¹ | 输出 | I2C 数据输出使能 |
¹ N = I2C_INST
表 14 UART 端口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 UART_INST 时可用。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_uart_rx | 输入 | UART 接收 |
i_uart_cts | 输入 | UART 清除发送 |
o_uart_tx | 输出 | UART 发送 |
o_uart_rts | 输出 | UART 请求发送 |
o_uart_busy | 输出 | UART 忙 |
表 15 GPIO 端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_gpio[N-1:0]¹ | 输入 | GPIO 输入。与 i_apb_clk 同步。 |
o_gpio[N-1:0]¹ | 输出 | GPIO 输出。与 i_apb_clk 同步。 |
o_gpio_dir[N-1:0]¹ | 输出 | GPIO 方向。0 = GPIO 输出,1 = GPIO 输入。用户可使用此端口将 GPIO 引脚置为三态。与 i_apb_clk 同步。 |
¹ N = GPIO_INST
表 16 传感器复位端口
| 信号名称 | 方向 | 描述 |
|---|---|---|
o_sw_sen_rst [31:0] | 输出 | 寄存器控制的复位。连接到板载传感器复位引脚。 |
o_sw_sys_rst | 输出 | 寄存器控制的自清除复位。可用于复位 PCS 等模块。 |
PTP 时钟与复位
表 17 PTP 时钟与复位
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_ptp_clk | 输入 | PTP 时钟 |
o_ptp_rst | 输出 | PTP 复位 |
表 18 内部 PTP 端口
以下端口仅在 “HOLOLINK_def.svh” 中未定义 EXT_PTP 时可用。PTP 模块在 HSB IP 内部实例化,用于同步和时间戳。
| 信号名称 | 方向 | 描述 |
|---|---|---|
o_ptp_sec [47:0] | 输出 | PTP 秒字段,符合 PTP1588-2019 v2 规范。与 i_ptp_clk 同步。 |
o_ptp_nanosec [31:0] | 输出 | PTP 纳秒字段,符合 PTP1588-2019 v2 规范。与 i_ptp_clk 同步。 |
o_pps | 输出 | 每秒脉冲(Pulse Per Second)。与 i_ptp_clk 同步。 |
表 19 外部 PTP 端口
以下端口仅在 “HOLOLINK_def.svh” 中定义了 EXT_PTP 时可用。如果以太网 MAC IP 内置了 PTP 功能,则可用于将时间戳传递给 HSB IP。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_ptp_sec [47:0] | 输入 | PTP 秒字段,符合 PTP1588-2019 v2 规范。与 i_ptp_clk 同步。 |
i_ptp_nanosec [31:0] | 输入 | PTP 纳秒字段,符合 PTP1588-2019 v2 规范。与 i_ptp_clk 同步。 |

以下是该页面的完整中文翻译,按照原文结构整理为单个大表格:
3. 时钟与复位 | Holoscan Sensor Bridge 文档
时钟
系统中有 4 个主要时钟:主机接口(HIF)时钟、APB 接口时钟、传感器接口(SIF)时钟和 PTP 接口时钟。
主机接口信号用于连接以太网 MAC 进行数据收发。因此,主机接口带宽(时钟频率 × 数据位宽)应支持设计的以太网带宽。
例如,在将 Holoscan Sensor Bridge IP 集成到 10G 应用中时,常用的时钟频率和数据位宽分别为 156.25MHz 和 64 位。如果系统以太网 MAC 输出 156.25MHz 时钟,一种可行的设计是直接使用以太网 MAC 的输出时钟作为主机接口时钟。如果系统无法直接使用以太网 MAC 时钟,则可以使用双时钟 FIFO 来匹配以太网 MAC 的带宽。最终,时钟架构由目标应用和所使用的 FPGA 厂商决定。
传感器接口时钟(i_sif_rx_clk 和 i_sif_tx_clk)驱动前端传感器 AXI-Stream 接口。每个传感器 AXI-Stream 接口都有一个独立的时钟输入,可以以独立的频率运行。
传感器 AXI-Stream 信号在 Holoscan Sensor Bridge IP 内部通过双时钟 FIFO 跨时钟域转换到主机接口时钟域。
复位
Holoscan Sensor Bridge IP 从一个主异步复位输入端,输出与各对应时钟同步的复位信号。
输入复位端口(i_sys_rst)为高电平有效异步复位。该端口应连接到板载复位引脚(图中标记为 RESET,高电平有效),并与 PLL 锁定信号进行门控。这样可确保在 PLL 锁定之前,Holoscan Sensor Bridge IP 保持复位状态。
输入和输出复位的连接示例如下图所示。

图 1 参考设计复位连接
下表描述了各输出复位及其在置位和释放时的时钟关系。
表 1 复位置位与释放
| 复位信号 | 置位(Assertion) | 释放(Deassertion) | 描述 |
|---|---|---|---|
o_apb_rst | 异步 | 与 i_apb_clk 同步 | 可用于复位 IP 外部的 APB 逻辑 |
o_hif_rst | 异步 | 与 i_hif_clk 同步 | 可用于复位 IP 外部的主机逻辑 复位在 o_apb_rst 释放之后才释放 |
o_sif_rx_rst[N-1:0]¹ | 异步 | 与 i_sif_rx_clk[N-1:0] 同步 | 可用于复位 IP 外部的传感器接口逻辑 复位在 o_apb_rst 释放之后才释放 |
o_sif_tx_rst[M-1:0]¹ | 异步 | 与 i_sif_tx_clk[M-1:0] 同步 | 可用于复位 IP 外部的传感器接口逻辑 复位在 o_apb_rst 释放之后才释放 |
o_ptp_rst | 异步 | 与 i_ptp_clk 同步 | 可用于复位 IP 外部的 PTP 逻辑 复位在 o_apb_rst 释放之后才释放 |
o_sw_sen_rst | 与 i_hif_clk 同步 | 与 i_hif_clk 同步 | 寄存器控制的传感器复位 可连接到 FPGA I/O 以复位板载传感器 |
o_sw_sys_rst | 与 i_hif_clk 同步 | 与 i_hif_clk 同步 | 寄存器控制的系统复位。可用于复位系统级逻辑 该复位还会触发 o_hif_rst、o_apb_rst 和 o_sif_rst 的复位 |
¹ N = SENSOR_RX_IF_INST, M = SENSOR_TX_IF_INST
4. 数据平面 | Holoscan Sensor Bridge 文档
数据平面是数据从传感器接口流向主机接口(以及反向)的通路。Holoscan Sensor Bridge IP 与传感器和主机之间通过 AXI-Stream 协议进行接口通信。AXI-Stream 是 AMBA 定义的一种总线协议,用于在端点之间传输数据。
Holoscan Sensor Bridge IP 采用的 AXI4-Stream 协议规范为 IHI0051B 修订版。
传感器与主机之间的带宽匹配是 Holoscan Sensor Bridge 集成中的一个重要考虑因素。传感器带宽必须小于或等于主机带宽,以避免反压(backpressure)。为了匹配主机带宽,传感器时钟可以运行在 156.25 MHz(前提是 AXI-S TVALID 始终为高),或者以双倍的时钟频率运行并每隔一个时钟周期置位 AXI-S TVALID。传感器时钟可以与主机时钟异步,但传感器的有效带宽必须小于或等于主机带宽。
传感器 RX(传感器 → FPGA)
在当前版本的 Holoscan Sensor Bridge IP 中,传感器 RX AXI-Stream 信号受以下约束:
- 每个
TVALID周期,完整的TDATA总线数据都会被发送到主机。 TLAST置高表示当前传感器窗口结束,并包含TLAST周期的数据。对于通用数据流,这是可选的;但当传感器具有有意义的帧边界时,建议使用,因为它会重新同步内部的每窗口字节计数器。有关传感器窗口的更多信息将在后文描述。TUSER信号用于相机应用,指示长包属性,如嵌入式数据或行结束。TKEEP信号被忽略。
在未来版本的 Holoscan Sensor Bridge IP 中,传感器 RX AXI-Stream 信号的预期功能为:
TKEEP信号将指示TDATA上待传输的有效字节。TKEEP仅在TLAST为高时有效。
传感器 RX AXI-Stream 的时序图示例见下图。该示例使用 39 字节传感器数据(DATAPATH_WIDTH=64)。图中的 D0、D1 等表示 1 字节。
注意,在 TLAST 时钟周期中,最高有效位(MSB)补零。补零后的数据将传输到主机。

图 1 传感器 RX AXI-Stream 接口
传感器窗口(Sensor Window)
在某些传感器应用中,窗口大小具有特定用途。例如,在相机传感器应用中,一帧中的字节数可以作为传感器窗口大小。
当到达传感器窗口末尾时,Holoscan Sensor Bridge(HSB)IP 会传输一个元数据包(metadata packet)。元数据包通知主机,缓冲在内存中的传感器数据已准备好被处理。更多详情请参阅 元数据包 章节。
传感器窗口结束可通过两种方式触发:
- 接收到的传感器数据字节数达到配置的传感器窗口大小。
i_sif_axis_tlast被置位。
理想情况下,计算的传感器窗口大小应与实际接收的传感器数据大小匹配。如果两者不同,置位 i_sif_axis_tlast 可以实现主机与 HSB IP 之间传感器窗口的重新同步。
- 如果
i_sif_axis_tlast在计算的传感器窗口大小之前被置位,会向主机发送一个元数据包,其中 Flags[0] 字段被置位以指示提前 TLAST,内部传感器窗口计数器重置为 0。 - 如果
i_sif_axis_tlast在窗口结束之后被置位,首先会向主机发送一个元数据包(表示到达配置的窗口末尾)。当i_sif_axis_tlast被置位时,会发送第二个元数据包;该第二个数据包被视为下一个窗口的提前 TLAST 条件。
在帧大小预期为动态变化的架构中,i_sif_axis_tlast 可用作生成帧结束的主要来源。在这种情况下,窗口大小应配置为最大预期值,允许 i_sif_axis_tlast 始终驱动窗口结束。
元数据包包含一个"缓冲区内有效字节数(Valid Number of Bytes within Buffer)"字段,可用于标识当前传感器窗口中传输的字节数。
相机数据流(Camera Streaming)
尽管 Holoscan Sensor Bridge 的传感器端口与数据格式无关,但在某些情况下,统一的数据格式更为可取。一个具体应用是相机数据流。为了与 IMX274 Holoscan 示例驱动程序无缝集成,MIPI CSI-2 相机数据必须按以下方式排列。这允许相同的驱动程序在不同 HSB 设备上工作。
用户可以采用与下面列出的不同的 MIPI CSI-2 格式,只要同时开发软件驱动程序来解码传入的 MIPI CSI-2 数据即可。当使用 CoE 格式时,请遵循 CoE 章节中描述的 CoE 像素格式。
除当前相机数据软件驱动程序的使用外,i_sif_axis_tdata 总线的格式没有限制。
用于 IMX274 示例的 MIPI CSI-2 相机数据的传感器 AXI-S 接口要求如下:
- 短 MIPI 包不得传输到传感器 AXI-S 接口。
- 长 MIPI 包的头部不得传输到传感器 AXI-S 接口。
- **长 MIPI 包的尾部(CRC)**不得传输到传感器 AXI-S 接口。
- **空包(Null)和消隐包(Blanking)**不得传输到传感器 AXI-S 接口。
- 每个长 MIPI 包应对齐到 8 字节边界。如有需要,可以补零。
- 像素数据必须保持 RAW 格式,例如 MIPI RAW10 格式。
- 在包含嵌入式数据(MIPI 数据类型 = 0x12)的周期中,应置位
i_sif_axis_tuser[0]。* - 在长包的最后一个时钟周期,应置位
i_sif_axis_tuser[1]。这被标识为**行结束(Line End)**信号。** - 在帧的最后一个周期,应置位
i_sif_axis_tlast(当帧边界可用时)。**
* i_sif_axis_tuser 信号仅用于需要内部图像信号处理(ISP)的高带宽相机。更多详情请联系 NVIDIA Holoscan 团队。
** 在帧的最后一个周期置位 i_sif_axis_tlast 是可选的,但强烈建议用于在计算和实际传感器窗口不同时重新同步帧。在帧结束包上置位 i_sif_axis_tlast 需要一个缓冲区来保存前一个长包,因为帧结束包在前一个长包之后一段时间才到达。
IMX274 1080p 格式化为传感器 RX AXI-S(DATAPATH_WIDTH=8)的示例如下图所示。

图 3 MIPI 到传感器 RX AXI-S 打包(DATAPATH_WIDTH=8)
IMX274 1080p 格式化为传感器 RX AXI-S(DATAPATH_WIDTH=64)的示例如下图所示。

图 4 MIPI 到传感器 RX AXI-S 打包(DATAPATH_WIDTH=64)
IMX274 1080p、RAW10 模式、DATAPATH_WIDTH=64 的传感器窗口计算示例如下图所示。

图 5 传感器窗口计算
传感器接口到虚拟端口映射(Sensor Interface to Virtual Port Mapping)
Holoscan Sensor Bridge IP 支持将多个传感器接口映射到虚拟端口以进行数据访问。该映射由 FPGA 参数 SIF_RX_NUM_VP 控制,该参数定义每个传感器接口的虚拟端口数量。当未显式配置时,SIF_RX_NUM_VP 默认对所有传感器为 1。虚拟端口映射仅在使用高带宽相机数据设置时有效。当未使用高带宽相机数据设置时,虚拟端口设置未定义,设为 0。软件通过这些虚拟端口索引与传感器数据交互。
虚拟端口按顺序串联在一起,每个传感器接口的虚拟端口按顺序分配。例如:
- 2 个传感器,
SIF_RX_NUM_VP={1,1}:- 传感器 0 的数据可在虚拟端口 0 访问
- 传感器 1 的数据可在虚拟端口 1 访问
- 2 个传感器,
SIF_RX_NUM_VP={2,2}:- 传感器 0 的数据可在虚拟端口 0 和 1 访问
- 传感器 1 的数据可在虚拟端口 2 和 3 访问
传感器事件(Sensor Event)
传感器事件信号可用于向主机生成中断消息。
例如,传感器事件信号可以连接到前端传感器 PHY 错误信号,以便在发生 PHY 错误时通知主机,并让主机执行软复位。
另一个例子,在相机应用中,帧结束可以连接到传感器事件信号,以便主机在帧之间更改相机设置。
中断消息可以在传感器事件信号的上升沿、下降沿或双边沿生成,具体通过软件 API 配置。传感器事件信号在 Holoscan Sensor Bridge IP 内部跨时钟域进入主机时钟域,因此传感器事件信号必须保持置位状态至少 2 个主机时钟周期。
传感器 TX(主机 → FPGA → 传感器)
主机可以通过 RoCE Send 包传输传感器数据。HSB IP 剥离 RoCE Send 包的网络头部和 CRC,然后通过 AXI-Stream 接口转发传感器数据。
主机 TX(FPGA → 主机)
传感器 RX 数据被封装为以太网包,并通过主机 TX AXI-Stream 端口传输。有几种不同的包格式可用:
- Camera over Ethernet (CoE)
- RDMA over Converged Ethernet (RoCE)
- 基于 Linux 的 UDP 套接字
在传感器窗口结束时,会发送一个元数据包以通知主机传感器帧或窗口已准备好处理。对于 RoCE,元数据包使用 Write with Immediate 操作来生成主机中断。
CoE
Camera over Ethernet(CoE)包以原生以太网包形式发出,使用 IEEE 1722B 风格的头部。与 RoCE 包不同,CoE 包不包含 IPv4、UDP、BTH、RETH 或 RoCE iCRC 字段。Holoscan Sensor Bridge IP 生成一个固定的 46 字节以太网/CoE 头部,然后附加传感器载荷。以太网 MAC 负责附加以太网帧校验序列(FCS)。
CoE 封装按传感器路径通过 is_1722b 配置位选择。选择 CoE 时,封装器使用配置的主机 MAC 地址作为目的 MAC 地址,设备 MAC 地址作为源 MAC 地址。
CoE 数据包格式
| 字节计数 | 描述 | 字节大小 | 字节序 | 备注 |
|---|---|---|---|---|
| 0 ~ 5 | 目的 MAC 地址 | 6 | 大端 | 软件配置的主机 MAC 地址 |
| 6 ~ 11 | 源 MAC 地址 | 6 | 大端 | 所选主机接口的设备 MAC 地址 |
| 12 ~ 13 | EtherType | 2 | 大端 | 0x22F0 |
| 14 | 子类型(Subtype) | 1 | 大端 | 0x82 |
| 15 ~ 17 | 状态有效和保留 | 3 | 大端 | 状态有效被置位;其余位保留并设为 0 |
| 18 ~ 25 | 流 ID(Stream ID) | 8 | 大端 | 0x00000000AAAAAAAA |
| 26 | ACF 消息类型 | 1 | 大端 | 0x0C |
| 27 | ACF 消息长度 | 1 | 大端 | 0x00 |
| 28 ~ 29 | MTV 和传感器 ID | 2 | 大端 | MTV 被置位;传感器 ID 为所选传感器接口索引 |
| 30 ~ 37 | PTP 时间戳 | 8 | 大端 | 当前 PTP 时间戳快照的低 64 位 |
| 38 ~ 41 | 序列号、标志和通道号 | 4 | 大端 | 序列号为包序列号[7:0];通道号为寄存器可配置 |
| 42 ~ 45 | 帧号和字节偏移 | 4 | 大端 | 包含帧号[1:0] 和载荷字节偏移 |
| 46 ~ N+45 | 传感器数据 | N | 小端 | 原始封装的传感器载荷 |
| N+46 ~ N+49 | 以太网 FCS | 4 | 小端 | 由以太网 MAC 添加,非 Holoscan Sensor Bridge IP 添加 |
CoE 标志字段(Flags)
| 位 | 描述 |
|---|---|
| 3:0 | 帧的第一个包为 0x1;帧结束元数据包为 0x2 |
| 7:4 | 当包跨越配置的阈值或行结束边界时为 0x1 |
在传感器窗口结束时,IP 还可以发出一个 CoE 元数据包。CoE 元数据包使用相同的 46 字节 CoE 头部,后跟下面描述的 48 字节元数据记录。元数据包使用 CoE 帧结束标志值。
CoE 元数据包格式
| 字节计数 | 描述 | 字节大小 | 字节序 | 备注 |
|---|---|---|---|---|
| 0 ~ 45 | CoE 头部 | 46 | 大端 | 与 CoE 传感器数据包字段相同 |
| 46 ~ 49 | 标志(Flags) | 4 | 小端 | 位 [0]:提前 TLAST。位 [1]:仅按每窗口字节数终止。位 [31:2]:保留 |
| 50 ~ 53 | 包序列号 | 4 | 小端 | 当前包的包序列号,位 [23:0],带填充 |
| 54 ~ 57 | 整个窗口传感器数据的 CRC | 4 | 小端 | 整个原始数据窗口的 CRC |
| 58 ~ 69 | 窗口第一个传感器数据的 PTP | 12 | 小端 | 帧第一个 i_sif_axis_tvalid 周期的 PTP 时间戳 |
| 70 ~ 77 | 缓冲区内有效字节数 | 8 | 小端 | FPGA 在帧内发送的有效字节数 |
| 78 ~ 81 | 帧号 | 4 | 小端 | 16 位帧计数器填充到 32 位 |
| 82 ~ 93 | 元数据包形成的 PTP | 12 | 小端 | FPGA 中创建元数据包时的 PTP 时间戳 |
| 94 ~ 97 | 以太网 FCS | 4 | 小端 | 由以太网 MAC 添加,非 Holoscan Sensor Bridge IP 添加 |
当 CoE 用于相机数据流时,载荷应遵循 CoE 像素格式。载荷不得包含 MIPI 短包、MIPI 长包头、长包 CRC 字节、空包或消隐包。像素行补零到 64 字节边界。tuser 在 CoE 中未使用,可驱动为低;tlast 应在帧的最后一个周期置位。像素样本按字节对齐用于 ISP 处理;例如,RAW10 打包为 {2'b0, P2[9:0], P1[9:0], P0[9:0]}。如果输入流使用 HSB 原始像素格式,封装器可以通过软件配置将其转换为 CoE 像素格式。
RoCE
RoCE 数据包格式
| 字节计数 | 描述 | 字节大小 | 字节序 | 备注 |
|---|---|---|---|---|
| 0 ~ 13 | 以太网头部 | 14 | 大端 | 按传感器软件配置的目的 MAC 地址 |
| 14 ~ 33 | IPv4 头部 | 20 | 大端 | 按传感器软件配置的目的 IPv4 地址 |
| 34 ~ 41 | UDP 头部 | 8 | 大端 | 按传感器软件配置的目的 UDP 端口 |
| 42 | BTH²:操作码(Opcode) | 1 | 大端 | 硬编码为 0x2A |
| 43 | BTH:请求事件(1b)、迁移请求(1b)、填充计数(2b)、传输头版本(4b) | 1 | 大端 | 硬编码为 0x0 |
| 44 ~ 45 | BTH:分区密钥(P_Key) | 2 | 大端 | 硬编码为 0xFFFF |
| 46 | BTH:FECN(1b)、BECN(1b)、保留(6b) | 1 | 大端 | 硬编码为 0x0 |
| 47 ~ 49 | BTH:目的 QP | 3 | 大端 | 按传感器软件配置 |
| 50 | BTH:确认请求(1b)、保留(7b) | 1 | 大端 | 硬编码为 0x0 |
| 51 ~ 53 | BTH:包序列号 | 3 | 大端 | 每个以太网包递增 |
| 54 ~ 61 | RETH³:虚拟地址 | 8 | 大端 | 软件配置的基地址,加上 DMA 偏移 |
| 62 ~ 65 | RETH:R_Key | 4 | 大端 | 按传感器软件配置 |
| 66 ~ 69 | RETH:DMA 长度 | 4 | 大端 | 软件可配置长度 |
| 70 ~ N+69¹ | 传感器数据 | N | 小端 | 从传感器 AXI-S 端口接收的原始数据 |
| N+70 ~ N+73¹ | iCRC | 4 | 小端 |
¹ N = 配置的以太网包长度或剩余的传感器窗口末尾大小。
² BTH:基础传输头部(Base Transport Header)
³ RETH:RDMA 扩展传输头部(RDMA Extended Transport Header)
基于 Linux 的 UDP(Linux UDP Based)
RoCE(RDMA over Converged Ethernet)通常与专用硬件和交换机支持相关联,用于实现真正的零拷贝、低延迟网络。然而,即使在网络交换机或硬件本身不支持 RoCE 的环境中,仍然可以在软件层面利用 RoCE 协议。在这种情况下,可以使用标准 Linux 套接字来传输和接收遵循 RoCE 包结构的以太网帧。应用程序或驱动程序可以直接从 UDP 载荷中解析相关的 RoCE 字段,如基础传输头部(BTH)、RETH 和其他协议特定头部。这种方法允许在没有完整硬件卸载或交换机支持的情况下,实现 RoCE 数据流的互操作性和测试,支持基于软件的 RDMA 仿真、协议开发,或与生成 RoCE 格式包的自定义 FPGA 或传感器平台的集成。虽然这种方法不提供硬件加速 RDMA 的完整性能优势,但它支持在标准以太网环境中灵活部署和开发。
元数据包(Metadata Packet)
RoCE 元数据包格式
| 字节计数 | 描述 | 字节大小 | 字节序 | 备注 |
|---|---|---|---|---|
| 0 ~ 13 | 以太网头部 | 14 | 大端 | 按传感器软件配置的目的 MAC 地址 |
| 14 ~ 33 | IPv4 头部 | 20 | 大端 | 按传感器软件配置的目的 IPv4 地址 |
| 34 ~ 41 | UDP 头部 | 8 | 大端 | 按传感器软件配置的目的 UDP 端口 |
| 42 | BTH:操作码 | 1 | 大端 | 0x2B |
| 43 | BTH:请求事件(1b)、迁移请求(1b)、填充计数(2b)、传输头版本(4b) | 1 | 大端 | 0x0 |
| 44 ~ 45 | BTH:分区密钥(P_Key) | 2 | 大端 | 0xFFFF |
| 46 | BTH:FECN(1b)、BECN(1b)、保留(6b) | 1 | 大端 | 0x0 |
| 47 ~ 49 | BTH:目的 QP | 3 | 大端 | 按传感器软件配置 |
| 50 | BTH:确认请求(1b)、保留(7b) | 1 | 大端 | 0x0 |
| 51 ~ 53 | BTH:包序列号 | 3 | 大端 | 每个以太网包递增 |
| 54 ~ 61 | RETH:虚拟地址 | 8 | 大端 | 软件配置的基地址,加上 DMA 偏移 |
| 62 ~ 65 | RETH:R_Key | 4 | 大端 | 按传感器软件配置 |
| 66 ~ 69 | RETH:DMA 长度 | 4 | 大端 | 软件可配置长度 |
| 70 ~ 73 | RETH:Write Immediate | 4 | 大端 | 包含 3 字节 BTH 包序列号,以及 1 字节用于标识传感器缓冲区 |
| 74 ~ 77 | 标志(Flags) | 4 | 小端 | 位 [0]:提前 TLAST。位 [1]:仅按每窗口字节数终止。位 [31:2]:保留 |
| 78 ~ 81 | 包序列号 | 4 | 小端 | BTH:包序列号 |
| 82 ~ 85 | 整个窗口传感器数据的 CRC | 4 | 小端 | 整个原始数据窗口的 CRC |
| 86 ~ 97 | 窗口第一个传感器数据的 PTP | 12 | 小端 | 帧第一个 i_sif_axis_tvalid 周期的 PTP 时间戳 |
| 98 ~ 105 | 缓冲区内有效字节数 | 8 | 小端 | FPGA 在帧内发送的有效字节数 |
| 106 ~ 109 | 帧号 | 4 | 小端 | 每帧递增的 16 位计数器 |
| 110 ~ 121 | 元数据包形成的 PTP | 12 | 小端 | FPGA 中创建元数据包时的 PTP 时间戳 |
| 122 ~ 201 | 保留 | 80 | 小端 | |
| 202 ~ 205 | iCRC | 4 | 小端 |
以太网、IPv4 和 UDP 头部遵循标准以太网头部格式。
RoCE 元数据包在帧或传感器窗口结束时发送。该包包含有关帧传输的元数据。它遵循 RoCE 协议,使用 0x2B 操作码,该操作码会向主机生成中断。
注意,帧校验序列(FCS)是以太网包的最后 4 个字节,是以太网包长度的一部分,但不是由 Holoscan Sensor Bridge IP 计算和添加的。以太网 IP 负责计算并将 FCS 添加到包末尾。
前导码(Preamble)和帧起始定界符(SFD)也由以太网 IP 添加;这些字段不计入以太网包长度。
传感器数据吞吐量(Sensor Data Throughput)
由于包开销,总传感器数据吞吐量小于可用的最大以太网带宽。
使用参考设计的以太网包长度 1486 字节,10G 以太网块的计算传感器数据吞吐量为 9.146Gbps。
考虑到以太网 IP 为每个以太网包添加的前导码、SFD 和帧间间隙(Interpacket Gap),总传感器吞吐量将进一步降低。
注意,传感器数据吞吐量取决于以太网包长度。较小的以太网包长度将导致较小的传感器数据吞吐量。
传感器数据延迟(Sensor Data Latency)
Holoscan Sensor Bridge IP 在接收到足够的传感器数据以构建完整的输出包后,开始封装传感器数据。从 Holoscan Sensor Bridge IP 输入端接收到包的最后一个传感器数据,到 Holoscan Sensor Bridge IP 输出端传输包的第一个数据之间的延迟为 50 个主机接口时钟周期。
这假设传输队列中没有其他待发送的包。
主机 RX(主机 → FPGA)
主机 RX 接口用于主机与 FPGA 通信。主机可以发送 BOOTP 响应、ICMP 回显请求和 NVIDIA 定义的以太网控制总线(ECB)包,以读写 FPGA 寄存器。
主机 RX AXI-Stream 端口必须连接到 MAC IP RX AXI-Stream 端口。Holoscan Sensor Bridge IP 主机 RX 期望帧校验序列(FCS)已被移除。
主机 RX AXI-Stream 端口符合 AMBA AXI-Stream 协议。TUSER 信号指示包错误(例如:帧校验序列错误)。TUSER 信号仅在 TLAST 为高时评估。
当 TUSER 与 TLAST 在同一周期为高时,Holoscan Sensor Bridge IP 将丢弃整个以太网包。
5. 控制平面 | Holoscan Sensor Bridge 文档
控制平面是主机对 Holoscan Sensor Bridge(HSB)IP 进行编程和查询的通路。主机将以太网控制总线(ECB)形式发送控制流量,HSB IP 解码 ECB 请求,执行 32 位对齐的高级外设总线(APB)读写操作,并在同一控制通路上返回读响应或确认包。
有关 APB 在 IP 内部的结构,请参阅 寄存器接口。
以太网控制总线(Ethernet Control Bus, ECB)
NVIDIA 将**以太网控制总线(ECB)定义为主机与 HSB 之间控制流量的用户数据报协议(UDP)**帧格式。HSB 解码 ECB 请求,并以 32 位读写方式驱动内部 APB 访问芯片的寄存器映射。
以下各节总结了 ECB 请求和响应的字节布局。除非另有说明,所有多字节字段均为大端序。寄存器地址和数据均为 32 位(4 字节),必须按 4 字节对齐。
主机到 HSB 的 ECB 包
主机到 HSB 的 ECB 包以一个固定的 14 字节头部开始。块读写命令附加额外的 8 字节记录:每个 APB 子事务包含一个 32 位地址和一个 32 位数值,最多达到块限制(请参阅 ECB 块读写)。
表 1. 主机到 HSB ECB 包(字节偏移)
| 字节偏移 | 字段 | 描述 |
|---|---|---|
| 0 | 命令码(Command code) | 见表 2 |
| 1 | 标志(Flags) | [7:2] 保留。[1] 序列检查。[0] 确认请求(仅适用于主机写命令) |
| 2–3 | 序列号(Sequence number) | 当序列检查标志置位时使用 |
| 4–5 | 保留 | 设为 0 |
| 6–9 | 地址 0(Address 0) | DWORD 命令:唯一的 32 位 APB 地址。BLOCK 命令:块中的第一个地址 |
| 10–13 | 数据 0(Data 0) | WRITE 命令:第一个 32 位写数据。READ 命令:设为 0 或无关 |
| 6+8m – 9+8m | 地址 m(Address m) | BLOCK 命令专用,m = 1, 2, …(第二对从字节 14 开始,第三对从 22 开始,依此类推) |
| 10+8m – 13+8m | 数据 m(Data m) | WRITE_BLOCK:地址 m 的写数据。READ_BLOCK:无关(例如 0) |
对于 WRITE_DWORD 和 READ_DWORD,包在字节 13 处结束(共 14 字节)。对于块命令,地址(4 字节)+ 数据(4 字节)的模式重复:第 m 对使用字节偏移 6+8m 到 13+8m,m = 0, 1, … 直到块大小减一。
表 2. 主机 ECB 命令码
| 命令 | 码值 |
|---|---|
| WRITE_DWORD | 0x04 |
| WRITE_BLOCK | 0x09 |
| READ_DWORD | 0x14 |
| READ_BLOCK | 0x19 |
单个 ECB 块读或块写最多可携带 511 个 APB 读或写操作(请参阅 ECB 块读写)。
HSB 到主机的 ECB 响应包
HSB 通过在主机命令码上加 0x80 来镜像主机的命令(表 3)。字节 4 是 HSB 对请求的状态(表 4),与字节 0 的字段不同。
READ_DWORD 和 WRITE_DWORD 成功响应使用短固定布局。READ_BLOCK 和 WRITE_BLOCK 成功响应为每个完成的 32 位访问添加 8 字节(地址和数据),然后是锁存序列号。
表 3. HSB ECB 响应命令(字节 0)
| 对应的主机命令 | 码值(字节 0) |
|---|---|
| WRITE_DWORD | 0x84 |
| WRITE_BLOCK | 0x89 |
| READ_DWORD | 0x94 |
| READ_BLOCK | 0x99 |
表 4. HSB 状态码(响应的字节 4)
| 状态 | 码值 |
|---|---|
| SUCCESS | 0x00 |
| INVALID ADDRESS / APB TIMEOUT | 0x03 |
| INVALID COMMAND | 0x04 |
| INVALID FLAG | 0x06 |
| SEQUENCE CHECK ERROR | 0x0B |
Holoscan 主机软件在解析响应时可能会映射这些以及额外的软件端错误码;上表匹配 HSB 用于 APB 和 ECB 错误的结果码。
READ_DWORD 或 WRITE_DWORD 响应(成功)
表 5. READ_DWORD 或 WRITE_DWORD 的响应布局(典型成功)
| 字节偏移 | 字段 | 描述 |
|---|---|---|
| 0 | 响应命令 | 0x94(读)或 0x84(写) |
| 1 | 标志 | [7:2] 保留。[1] 序列检查。[0] 确认响应 |
| 2–3 | 序列号 | 适用时回显主机请求 |
| 4 | HSB 状态 | 状态码 |
| 5 | 保留 | 0x0 |
| 6–9 | 地址 | 请求中的 32 位 APB 地址 |
| 10–13 | 读数据或保留 | READ_DWORD:32 位读数据。WRITE_DWORD:保留 |
| 14–15 | 锁存序列号 | 使用序列检查时,复制主机 ECB 序列 |
READ_BLOCK 或 WRITE_BLOCK 响应(成功)
表 6. READ_BLOCK 或 WRITE_BLOCK 的响应布局(与表 5 的前导字节 0–4 相同)
| 字节偏移 | 字段 | 描述 |
|---|---|---|
| 0 | 响应命令 | 0x99(读)或 0x89(写) |
| 1 | 标志 | [7:2] 保留。[1] 序列检查。[0] 确认响应 |
| 2–3 | 序列号 | 适用时回显主机请求 |
| 4 | HSB 状态 | 状态码 |
| 5 | 保留 | 0x0 |
| 6+8m – 9+8m | 地址 m | m = 0, …, N−1。与主机请求相同的配对方式 |
| 10+8m – 13+8m | 数据 m | READ_BLOCK:地址 m 的 32 位读数据。WRITE_BLOCK:保留或由实现定义 |
| 6+8N – 7+8N | 锁存序列 | 对于 N 个 32 位操作,两字节的锁存序列从此偏移开始(例如 N=1 时为 14–15,N=2 时为 22–23) |
ECB 块读写(ECB block read and write)
块 ECB 命令在一个 UDP 消息中发出多个连续的 32 位 APB 操作。单个 ECB 块读或块写中 APB 读或写事务的最大数量为 511。
每个地址必须按 4 字节对齐。Holoscan Sensor Bridge IP 和主机软件强制一次只能有一个未完成的 ECB 请求;在收到前一个命令的响应(或软件中超时)之前,不应发送新请求。
序列号检查(Sequence number check)
序列号检查提高了 ECB 包在网络中重排序或丢失时的鲁棒性。当 Flags 字段中的序列检查位被置位时,HSB IP 检查新接收的 ECB 序列号是否恰好比该控制通路上先前接收的 ECB 序列号大 1(模序列宽度)。如果新序列号无效,HSB 会发送一个 HSB 状态为 SEQUENCE CHECK ERROR (0x0B) 的 ECB 响应。此检查有助于验证 HSB 是否按顺序接收了主机的 ECB 流。
当未启用序列检查时,HSB 不应用此严格的递增规则;但如果共享单个 HSB 执行通道,主机仍应避免重叠的控制命令。
6. 外设接口 | Holoscan Sensor Bridge 文档
Holoscan Sensor Bridge IP 支持多种软件定义的外设接口:SPI、I2C、UART 和 GPIO。每种协议都实例化一个通用核心来处理所有协议特定的需求,并允许软件配置事务,然后由 Holoscan Sensor Bridge IP 执行。
使用单个核心实例可以支持多个端点。这减少了整体资源利用率,无需多个核心实例。然而,这带来了一个要求:每个协议一次只能设置和执行一个事务,因为所有端点共享相同的物理寄存器。
外设核心及其事务通过 ECB 包进行配置。该系统允许软件将一系列数据字节加载到缓冲区中,然后写入外设。来自外设的任何数据将存储到同一缓冲区中,随后可通过 ECB 读取操作读取。
外设接口使用 i_apb_clk 时钟,并由 o_apb_rst 复位。预分频器寄存器可配置为所需的外设接口频率。
SPI
SPI 核心为每个连接的端点提供一个 4 位双向数据信号(SDIO)、一个片选信号(CS_N)和一个时钟信号(SCK)。双向数据信号被拆分为 4 位输入和 4 位输出信号,并带有一个输出使能(OEN)信号用于三态控制。该 SPI 核心支持单 SPI 模式,使用 SDIO[0] 作为输出(MOSI),SDIO[1] 作为输入(MISO)。双 SPI 和四 SPI 分别使用 SDIO 信号的 2 位和 4 位。
顶层输入应与 i_apb_clk 时钟域同步。以下代码片段演示了如何将 Holoscan Sensor Bridge SPI 接口连接到顶层端口,其中 “i” 为端点索引。SPI_SCK、SPI_CSN、SPI_MOSI、SPI_MISO 和 SPI_SDIO 为顶层端口。

图 1. 简单 SPI 连接
assign SPI_SCK = o_spi_sck [i];
assign SPI_CSN = o_spi_csn [i];
assign SPI_MOSI = o_spi_sdio [i];
assign i_spi_sdio[i] = {2'b0, SPI_MISO, 1'b0};

图 2. 双/四 SPI 连接
双 SPI 赋值
assign SPI_SCK = o_spi_sck [i];
assign SPI_CSN = o_spi_csn [i];
assign SPI_SDIO [1:0] = o_spi_oen [i] ? o_spi_sdio[i][1:0] : 2'bz;
assign i_spi_sdio [i] = {2'b0, SPI_SDIO};
四 SPI 赋值
assign SPI_SCK = o_spi_sck [i];
assign SPI_CSN = o_spi_csn [i];
assign SPI_SDIO = o_spi_oen [i] ? o_spi_sdio[i] : 4'bz;
assign i_spi_sdio [i] = SPI_SDIO;
SPI CTRL FSM 的基地址为 0x0300_0000。
I2C
I2C 核心有两个双向信号:sda 和 scl。该核心使用一个输入信号和一个输出使能信号来实现这种双向信号。当输出使能信号为高时,对应的信号应悬空;只有当输出使能为低时,输出才应被拉低。此行为与 I2C 协议一致。
I2C 核心支持 I2C 时钟拉伸(clock stretching)。
顶层输入应与 i_apb_clk 时钟域同步,并且根据 I2C 协议还应添加毛刺滤波(glitch filtering)。
以下代码片段演示了如何将 Holoscan Sensor Bridge I2C 接口连接到顶层端口,其中 “i” 为端点索引。I2C_SCL 和 I2C_SDA 为顶层端口。

图 3. I2C 连接
I2C 赋值
assign i_i2c_scl[i] = o_i2c_scl_en[i] ? I2C_SCL : 1'b0;
assign i_i2c_sda[i] = o_i2c_sda_en[i] ? I2C_SDA : 1'b0;
assign I2C_SCL = o_i2c_scl_en[i] ? 1'bz : 1'b0;
assign I2C_SDA = o_i2c_sda_en[i] ? 1'bz : 1'b0;
I2C CTRL FSM 的基地址为 0x0300_0200。
* 注意:I2C 仅在 400kHz 速度模式下经过验证和测试。
UART
UART 核心提供一个标准的异步串行接口,具有可配置的帧格式和可通过 UART 除数寄存器编程的波特率。该核心支持常见的 UART 波特率:9600、38400、57600 和 115200(以及可通过 APB 时钟使用波特率除数设置生成的其他速率)。
UART 接口应在顶层连接,每个端点有一个 TX 输出和一个 RX 输入。将 HSB UART TX 输出连接到外部 UART RX 引脚,将外部 UART TX 引脚连接到 HSB UART RX 输入。如果需要硬件流控制,还需在 HSB IP 和外部接口之间连接 RTS/CTS。UART 核心已包含内部 RX 毛刺滤波支持,因此不需要额外的外部毛刺滤波逻辑。
UART TX 和 RX 数据通过 APB 接口访问。
UART CTRL FSM 的基地址为 0x0300_0400。
GPIO
Holoscan Sensor Bridge IP 支持**通用输入/输出(GPIO)**信号,用于状态和控制功能。
GPIO 信号可以连接到内部用户逻辑或板卡顶层。GPIO 控制的示例包括切换板载引脚、IP 配置的内部绑带、LED 控制等。
GPIO 状态的示例包括传感器状态信号、板载和内部校准完成信号、软件复位计数等。
GPIO 控制信号的复位值可使用 GPIO_RESET_VALUE 参数定义。
以下代码片段演示了如何将 Holoscan Sensor Bridge GPIO 接口作为 INOUT 端口连接到顶层,其中 “i” 为端点索引。
GPIO 赋值
assign i_gpio[i] = GPIO[i];
assign GPIO[i] = o_gpio_dir[i] ? 1'bz : o_gpio[i];
GPIO 输入信号将通过**时钟域交叉(CDC)进入 i_apb_clk 时钟域。GPIO 输出信号将通过时钟域交叉(CDC)**进入 i_hif_clk 时钟域。

图 4. GPIO 连接
在 Lattice CPNX100-ETH-SENSOR-BRIDGE 开发套件中,HSB IP 的 GPIO 连接到测试点和 Jetson 连接器。Lattice 开发套件中 HSB IP GPIO 映射如下。
Lattice CPNX100-ETH-SENSOR-BRIDGE GPIO 引脚
| HSB IP | Lattice HSB |
|---|---|
| GPIO[0] | J20, pin 3 |
| GPIO[1] | J20, pin 5 |
| GPIO[2] | J20, pin 7 |
| GPIO[3] | J20, pin 9 |
| GPIO[4] | J20, pin 11 |
| GPIO[5] | J20, pin 13 |
| GPIO[6] | J20, pin 15 |
| GPIO[7] | J20, pin 17 |
| GPIO[8] | J20, pin 4 |
| GPIO[9] | J20, pin 6 |
| GPIO[10] | J20, pin 8 |
| GPIO[11] | J20, pin 10 |
| GPIO[12] | J20, pin 12 |
| GPIO[13] | J20, pin 14 |
| GPIO[14] | J20, pin 16 |
| GPIO[15] | J20, pin 18 |
| GPIO[16] | J9, pin 76 |
| GPIO[17] | J9, pin 78 |
| GPIO[18] | J9, pin 84 |
| GPIO[19] | J9, pin 85 |
| GPIO[20] | J9, pin 90 |
| GPIO[21] | J9, pin 92 |
| GPIO[22] | J9, pin 96 |
| GPIO[23] | J9, pin 97 |
| GPIO[24] | J9, pin 98 |
| GPIO[25] | J9, pin 119 |
| GPIO[26] | J9, pin 86 |
| GPIO[27] | J9, pin 103 |
| GPIO[28] | J9, pin 104 |
| GPIO[29] | J9, pin 106 |
| GPIO[30] | J9, pin 117 |
7. 寄存器接口 | Holoscan Sensor Bridge 文档
**高级外设总线(Advanced Peripheral Bus, APB)**接口在 Holoscan Sensor Bridge IP 中用于内部寄存器表的读写事务。主机访问寄存器的 ECB 命令在 Holoscan Sensor Bridge IP 内部被转换为 APB 事务。
APB 是 AMBA 定义的一种低复杂度总线协议,具有固定的 32 位数据和地址总线宽度。Holoscan Sensor Bridge IP 采用的 APB 规范为 IHI0024E 版本(APB3)。
Holoscan Sensor Bridge IP 的寄存器映射如下图所示。

图 1. 寄存器映射
用户寄存器(User Registers)
用户寄存器块映射的地址范围为 0x1000_0000 到 0x8FFF_FFFF,并按 REG_INST 宏定义的实例数量细分为多个子块,每个子块跨度为 0x1000_0000。
Holoscan Sensor Bridge IP 上可用的 APB 端口允许用户连接到用户特定的模块,例如以太网 MAC/PCS IP 块或传感器接口寄存器,此时 Holoscan Sensor Bridge IP 作为 APB 请求方(Requester)。
寄存器地址的最高位 msb[31:28] 用于确定 REG_INST_# 块,地址 [27:0] 为偏移地址。
例如,如果主机访问 0x1000_0000 – 0x1FFF_FFFF 地址映射中的寄存器,这将触发 o_apb_psel[0],偏移地址 o_apb_paddr 映射为 0x0000_0000 – 0x0FFF_FFFF,依此类推。

图 2. 寄存器实例偏移
将未使用的 REG_INST APB pready、prdata 和 pslverr 信号连接到 0。
Holoscan Sensor Bridge IP APB 总线支持 4 字节读和 4 字节写。如果需要小于 4 字节的读写操作,用户可以实现字节掩码逻辑。
如果在 256 个时钟周期内未从 APB 完成方(Completer)收到响应,APB 总线将超时。如果达到超时,Holoscan Sensor Bridge IP 将在 ECB 上响应无效地址。
以下是将 2 个以太网 IP 分别连接到用户寄存器子块的示例连接图。

图 3. 用户寄存器子块
8. PTP
HSB IP supports Precision Time Protocol (PTP) per IEEE1588-2019 specification.
For detailed information regarding PTP implementation in the HSB IP, refer to the
PTP Application Note.
9. PTP 应用说明 | Holoscan Sensor Bridge 文档
Holoscan Sensor Bridge(HSB)IP 支持符合 IEEE1588-2019 规范的精确时间协议(Precision Time Protocol, PTP)版本 2。
PTP 将主机时间同步到所有下游设备。要将主机配置为**时间发送方(Time Transmitter)**并发送 PTP 包,请参阅 主机设置 页面。
通过在 “HOLOLINK_def.svh” 中定义 EXT_PTP(即外部 PTP),可以移除 HSB IP 的 PTP 实例化。定义 EXT_PTP 将向 HSB IP 暴露不同的 I/O,用于将外部 PTP 时间戳输入到 HSB IP。更多信息请参阅 端口描述。重要提示:当定义 EXT_PTP 时,i_pps 端口需要每秒切换一次。与主机的枚举通过 BOOTP 消息完成,该消息由 PPS 触发。
用例
同步的 PTP 时间可用于:
- 为特定的传感器接口和主机接口事件添加时间戳。请参阅 元数据包 了解传输到主机的 PTP 时间戳事件。
- 同步网络上的多个 HSB。
- 在相机应用中,同步的垂直同步(Vertical SYNC, VSYNC)脉冲可以对齐网络上多个相机的曝光开始时间。更多信息请参阅 VSYNC。
配置文件(Profile)
HSB IP 支持以下 PTP 配置文件:
- 1588 配置文件,采用端到端延迟机制(End to End Delay Mechanism)(默认)
- gPTP 配置文件,采用点对点延迟机制(Peer to Peer Delay Mechanism)
- 1588 配置文件,采用点对点延迟机制(Peer to Peer Delay Mechanism)
HSB IP 的 PTP 实现限制如下:
- 仅作为 **PTP 接收方(Receiver)**运行
- 仅通过以太网 L2 层传输和接收 PTP 消息
- 不支持 Announce 消息
- 不支持最佳主时钟算法(Best Master Clock Algorithm)。它假设在给定时间网络中只有 1 个主时钟
- PTP 流量只能在 HSB IP 主机接口 0 上发生
PTP 流程
PTP 消息与时间戳
- 时间戳 1(T1):主机通过发送 SYNC 和 FOLLOW-UP(两步模式下)消息广播其当前时间。
- 时间戳 2(T2):HSB 在接收到 SYNC 消息时为其当前时间打戳。
- 时间戳 3(T3):HSB 在接收到 SYNC/FOLLOW-UP 消息后发送 Delay Request 消息。(用于端到端延迟机制)
- 时间戳 4(T4):主机在接收到 Delay Request 消息时为其当前时间打戳,并发送 Delay Response 消息。
有了 4 个可用的时间戳,HSB IP 可以计算偏移测量(Offset Measurement, OFM)和平均延迟(Mean Delay)。
点对点延迟机制具有不同的 PTP 消息和时序,但其平均延迟测量的概念类似。
采用端到端延迟机制的 PTP 消息流程如下图所示。

PTP 定时器
PTP 模块运行在 i_ptp_clk 时钟域。i_ptp_clk 可以与 i_hif_clk 时钟域异步,但为了获得最佳性能,建议生成从恢复的以太网 PCS 或 MAC 时钟派生的时钟。推荐的 PTP 时钟频率为 95MHz 到 105MHz。
PTP 定时器序列:
- 复位后,定时器从 0 秒和 0 纳秒开始。在每个上升沿,定时器增加
(1/PTP_CLK_FREQ)纳秒和 24 位小数纳秒,其中PTP_CLK_FREQ是 “HOLOLINK_def.svh” 中定义的参数。例如,在 10G 应用中,PTP_CLK_FREQ=100446545,派生自恢复的以太网 PCS 时钟,每个上升沿的增量值为 9.955ns。 - 当 PTP 启用时,HSB IP 将主机时间戳(T1)锁存为其当前时间,定时器继续像以前一样递增。这使定时器能够赶上当前的 PTP 时间。
- 在后续的 SYNC 消息中,使用时间戳(T1-T4)计算**偏移测量(OFM)**并调整定时器的增量值。调整增量值(频率的倒数)可以补偿板载振荡器漂移和温度变化。
偏移测量(Offset Measurement)
**偏移测量(OFM)**是主机时间与 HSB IP 时间之间的时间偏移。当主机时间(T1)到达 HSB IP 时,由于平均延迟、交换机驻留时间和延迟不对称等因素,时间戳已经过时。针对各种延迟调整 OFM 可以计算出更准确的偏移,从而实现更精确的同步。
- 平均延迟(Mean Delay)
- 平均延迟定义为主机到 HSB 和 HSB 到主机的平均网络延迟。平均延迟样本在移动窗口中进一步平均,以平滑异常值。
- 交换机驻留时间(Switch Residence Time)
- 主机与 HSB 之间的网络连接可以是直接连接,也可以通过多个交换机将多个 HSB 聚合到单个主机。网络中的每个交换机都会增加驻留时间,即 PTP 消息穿越交换机所需的时间。此驻留时间附加到 PTP 消息的**修正字段(Correction Field)**中。
- 延迟不对称(Delay Asymmetry)
- 延迟不对称定义为以太网包入站和出站之间的时间差。HSB IP 内部的延迟不对称会自动计算。
HOST_WIDTH参数会影响消耗 PTP 消息所需的时钟周期数,这会增加入站延迟。 - HSB IP 外部(FPGA 厂商的以太网 MAC 和 PCS IP 中)也存在延迟不对称。这是厂商特定的,可使用 PTP 延迟不对称寄存器进行编程。
- 延迟不对称定义为以太网包入站和出站之间的时间差。HSB IP 内部的延迟不对称会自动计算。
频率调整数字锁相环(Frequency Adjustment Digital PLL, DPLL)
偏移测量(OFM)馈入数字锁相环(DPLL),产生一个频率调整值。在定时器中,该调整作为每个时钟增量的修正应用,从而使闭环跟踪主机时间。**粗增益(Coarse Gain)和细增益(Fine Gain)**是可编程寄存器:每个通过对 OFM 进行算术右移来缩放。

寄存器
以下列出可配置的 PTP 寄存器。
| 寄存器名称 | 寄存器地址 | 寄存器值范围 | 默认值 | 备注 |
|---|---|---|---|---|
| 增益使能(Gain Enable) | 0x00000104 | 0x0 - 0x3 | 0x3 | 启用频率调整增益。[0]=粗增益,[1]=细增益 |
| PTP 配置文件(PTP Profile) | 0x00000108 | 0x0 - 0x2 | 0x0 | PTP 配置文件。[0]=1588 E2E,[1]=gPTP,[2]=1588 P2P |
| 延迟不对称(Delay Asymmetry) | 0x0000010C | 0x00000000 - 0xFFFFFFFF | 0x33 | 入站不对称,二进制补码。单位为纳秒。 |
| 粗增益(Coarse Gain) | 0x00000110 | 0x0 - 0xF | 0x2 | 频率调整粗增益 |
| 细增益(Fine Gain) | 0x00000114 | 0x0 - 0xF | 0x2 | 频率调整细增益 |
| 平均延迟平均因子(Mean Delay Avg Factor) | 0x00000118 | 0x0 - 0x3 | 0x3 | 按 2 的因子平均。因此 0x1 = 2 个样本,0x2 = 4 个样本,依此类推 |
| PTP 域(PTP Domain) | 0x0000011C | 0x0 - 0xFF | 0x0 | PTP 域编号。不匹配的 PTP 消息将被忽略。 |
以下列出 PTP 状态寄存器。
| 寄存器名称 | 寄存器地址 | 备注 |
|---|---|---|
| SYNC 时间戳(SYNC Timestamp) | 0x00000180 | 接收到的 PTP SYNC 时间戳值 |
| SYNC 修正字段(SYNC Correction Field) | 0x00000184 | 接收到的 PTP SYNC 修正字段值 |
| PTP 状态(PTP Status) | 0x00000188 | 状态。[0]=接收到 SYNC 消息。[1]=接收到 SYNC 消息且 PTP 已启用。[2]=接收到 Delay Response 消息。[3]=接收到 Delay Response 消息且 PTP 已启用。 |
| OFM | 0x0000018C | 计算的偏移测量值 |
| 平均延迟(Mean Delay) | 0x00000190 | 计算的平均延迟值 |
| 增量周期(Increment Period) | 0x00000194 | 每个周期的当前增量值。[31:24] 纳秒 [23:0] 小数纳秒 |
| 频率调整(Frequency Adjustment) | 0x00000198 | 计算的频率调整值 |
以下是一个重新配置 PTP 的示例 Python 脚本。示例中使用的值为复位后的默认配置。
def ptp_enable(hololink):
hololink.write_uint32(0x00000108, 0x00000000) # PTP 配置文件
hololink.write_uint32(0x0000010C, 0x00000033) # 延迟不对称
hololink.write_uint32(0x00000110, 0x00000002) # DPLL 配置 1
hololink.write_uint32(0x00000114, 0x00000002) # DPLL 配置 2
hololink.write_uint32(0x00000118, 0x00000003) # 平均延迟
hololink.write_uint32(0x00000104, 0x00000003) # 启用 DPLL
性能
PTP 的性能通过示波器比较主机和 HSB IP 之间的**每秒脉冲(Pulse Per Second, PPS)**进行测试。

性能测试使用以下配置进行。
| 参数或寄存器 | 值 |
|---|---|
| (主机)logSyncInterval | -3(每秒 8 次) |
| HIF_CLK_FREQ | 156250000Hz |
| PTP_CLK_FREQ | 100446545Hz |
| 增益使能 | 0x3 |
| 延迟不对称 | 0x33 |
| 粗增益 | 0x2 |
| 细增益 | 0x2 |
| 平均延迟平均因子 | 0x3 |
PPS 测量的示波器捕获如下图所示。

| 偏移 | 端到端标准差 |
|---|---|
| < 10 ns | < 25 ns |
调试
- PTP 状态 [0] = 0, [1] = 0
- 未接收到 SYNC/FOLLOW-UP 消息。
- 在 Wireshark 中检查主机是否正在传输 PTP 消息。
- 如果主机正在传输 PTP 消息但 HSB 未传输任何 PTP 消息,请检查主机 PTP 包的 MajorSdoID 字段。
- 对于 1588 配置文件,MajorSdoID 应为 0。
- 对于 gPTP 配置文件,MajorSdoID 应为 1。
- 未接收到 SYNC/FOLLOW-UP 消息。
- PTP 状态 [0] = 1, [1] = 0
- 接收到 SYNC/FOLLOW-UP 消息,但 HSB IP PTP 未启用。
- PTP 状态 [0] = 1, [1] = 1
- PTP 已启用并成功接收到 PTP 消息。
- OFM
- 快速连续读取 OFM 寄存器。如果频率调整 DPLL 稳定,OFM 应在 -100 到 +100 之间稳定接近 0。如果 OFM 振荡且幅度增长,DPLL 可能不稳定,请增加粗增益和细增益寄存器。
VSYNC
在相机应用中,垂直同步(Vertical SYNC, VSYNC)或有时称为帧同步(Frame SYNC, FSYNC),控制该帧的相机曝光开始。连接到多个 HSB 的多个相机可以通过 PTP 同步到单个主机。从同步的 PTP 时间,可以生成 VSYNC 以同步帧捕获的开始。

VSYNC RTL 集成
参考设计 “vsync_gen” RTL 模块可以基于当前时间戳生成 VSYNC 脉冲。“vsync_gen” 模块的端口如下。
| 信号名称 | 方向 | 描述 |
|---|---|---|
i_clk | 输入 | PTP 时钟 |
i_rst | 输入 | PTP 复位,与 PTP 时钟域同步 |
i_pps | 输入 | 每秒脉冲,PTP 时钟域 |
i_ptp_nanosec[31:0] | 输入 | PTP 纳秒时间戳,PTP 时钟域 |
o_vsync_strb | 输出 | VSYNC 脉冲,PTP 时钟域 |
o_gpio_mux[9:0] | 输出 | GPIO MUX 使能信号,PTP 时钟域 |
i_apb_clk | 输入 | APB 时钟 |
i_apb_rst | 输入 | APB 复位,与 APB 时钟域同步 |
i_apb_sel | 输入 | APB 选择 |
i_apb_enable | 输入 | APB 使能 |
i_apb_addr[31:0] | 输入 | APB 地址 |
i_apb_wdata[31:0] | 输入 | APB 写数据 |
i_apb_write | 输入 | APB 写 |
o_apb_ready | 输出 | APB 就绪 |
o_apb_rdata[31:0] | 输出 | APB 读数据 |
o_apb_serr | 输出 | APB 完成方错误 |
“vsync_gen” 模块可以在 HSB IP 的同一封装模块中实例化,其中 APB 信号连接到 HSB IP 的 APB 信号。VSYNC 模块的基地址将取决于 HSB IP 的 o_apb_psel 端口的哪一位被连接。更多信息请参阅 寄存器接口 页面。在 Lattice CPNX100-ETH-SENSOR-BRIDGE 参考设计中,“vsync_gen” 模块连接到 HSB IP 的 o_apb_psel[6],映射到 0x7000_0000 基地址。
VSYNC 寄存器配置
| 寄存器名称 | 寄存器地址偏移 | 寄存器值范围 | 备注 |
|---|---|---|---|
| 使能(Enable) | 0x0000 | 0x0 - 0x1 | 0=禁用,1=启用 |
| 频率模式(Frequency Mode) | 0x0004 | 0x0 - 0x3 | 0=10Hz,1=30Hz,2=60Hz,3=90Hz,4=120Hz |
| 延迟(Delay) | 0x0008 | 0x0 - 0xFFFFFFFF | 开始 VSYNC 置位前的延迟(纳秒) |
| 起始值(Start Val) | 0x000C | 0x0 - 0x1 | VSYNC 的起始状态。0=高电平有效,1=低电平有效 |
| 曝光时间(Exposure Time) | 0x0010 | 0x0 - 0xFFFFFFFF | 有效状态的持续时间(纳秒) |
| GPIO MUX 使能(GPIO MUX Enable) | 0x0014 | 0x0 - 0x3FF | GPIO MUX 控制信号 |
VSYNC Configuration
- 配置频率模式、延迟、起始值和曝光时间。
- 延迟和曝光时间应设置为小于配置频率的周期。
- 某些相机使用 VSYNC 信号的有效状态(曝光时间寄存器)作为相机的曝光时间。
- 启用 VSYNC
- 一旦启用,VSYNC 将在下一个**每秒脉冲(PPS)**信号开始时生成。
GPIO MUX 使能
GPIO MUX 使能寄存器用于强制将 VSYNC 信号路由到现有 GPIO。当将 VSYNC 信号路由到三态 HSB GPIO 时,三态应为最终赋值,以确保综合工具将 GPIO 放置到 INOUT 缓冲器。将 VSYNC 信号路由到三态 GPIO 的示例代码:
assign i_gpio[14] = GPIO[14];
assign GPIO[14] = o_gpio_dir[14] ? 1'bz : o_gpio_mux_en[1] ? o_vsync_strb : o_gpio[14];
在 Lattice CPNX100-ETH-SENSOR-BRIDGE 参考设计中,PPS 和 VSYNC 信号复用到几个 GPIO。强制 PPS 和 VSYNC 信号的位如下。
| GPIO MUX 使能位 | 信号 | HSB GPIO | 硬件引脚 |
|---|---|---|---|
| [0] | PPS | GPIO[15] | J20, pin18 |
| [1] | VSYNC | GPIO[14] | J20, pin16 |
| [3:2] | 保留 | 保留 | 保留 |
| [4] | VSYNC | GPIO[19] | J9, pin85 |
| [5] | VSYNC | GPIO[22] | J9, pin96 |
| [6] | VSYNC | GPIO[23] | J9, pin97 |
| [7] | VSYNC | GPIO[24] | J9, pin98 |
| [9:8] | 保留 | 保留 | 保留 |
10. VLAN 标记 | Holoscan Sensor Bridge 文档
Holoscan Sensor Bridge(HSB)IP 支持 IEEE 802.1Q VLAN 标记。VLAN 标记可用于通过**优先级代码点(Priority Code Point, PCP)字段对网络流量进行优先级排序,并使用虚拟 ID(Virtual IDs, VID)**对流量进行逻辑隔离。
IEEE 802.1Q VLAN 标记可与支持**时间敏感网络(Time Sensitive Networking, TSN)**的交换机配合使用,以确定性地整形网络流量。TSN 需要 IEEE 802.1Q VLAN 标记和 IEEE 802.1AS gPTP 同步两者。要配置主机和 HSB 的 gPTP 配置文件及 VLAN 子接口,请参阅 TSN IMX274 示例。
数据平面 VLAN 行为
每个数据平面传感器虚拟端口可配置为 VLAN 标记或未标记,并具有各自的 PCP 和 VID 值。3 位 PCP 字段用于整形数据平面流量,例如,所有相机传感器可设置为某个 PCP 值,IMU 传感器设置为不同的 PCP 值,以对传感器类型进行分组。
请参阅 TSN 配置序列 来配置带有 VLAN 标记的传感器数据平面。
控制平面 VLAN 行为
控制平面 VLAN 行为因类型而异。
例如,BOOTP 包始终未标记,以便主机始终可以在网络上枚举 HSB。
对于 ARP、PING、ECB 包,主机是发起方,HSB 是响应方,因此 HSB 会适应接收到的包。如果主机发送未标记的 ECB 包,HSB 将以未标记的 ECB 包响应;如果主机发送标记的 ARP 包,HSB 将以相同的 VLAN 标记响应。
以下列出了每种控制平面包及其 VLAN 行为的描述。
| 流量类型 | 线路上的 VLAN |
|---|---|
| ARP、PING、ECB | 自适应(Adaptive):如果主机发送 VLAN 标记帧,HSB 存储该标记并以相同的 802.1Q 标记响应。如果主机发送未标记流量,响应也为未标记。控制平面不需要 VLAN ID / PCP / 使能寄存器编程。 |
| 控制事件(Control events) | 寄存器编程:作为 TSN 配置序列的一部分。 |
| PTP | 仅未标记:gPTP/PTP 帧始终在不带 802.1Q 标记的情况下发送和接收。 |
| BOOTP(枚举) | TX 未标记:HSB 传输未标记的 BOOTP 枚举。主机枚举在父接口或配置的 BOOTP 绑定设备上监听。 |
11. 用户配置 | Holoscan Sensor Bridge 文档
顶层模块
Holoscan Sensor Bridge IP 的顶层模块为 “HOLOLINK_top”。
用户可配置性
Holoscan Sensor Bridge(HSB)IP 设计为可轻松配置以适应各种应用场景,例如传感器数量和以太网端口数量。它还设计为兼容多个 FPGA 厂商。以下描述了用户可用的配置选项。
宏定义
Holoscan Sensor Bridge 定义文件 “HOLOLINK_def.svh” 定义了以下宏。
这些宏可根据用户的 Holoscan Sensor Bridge IP 应用进行配置。默认宏值是经过测试和验证的配置。
表 1
| 宏 | 测试值 | 描述 |
|---|---|---|
HIF_CLK_FREQ | 156250000(DATAPATH_WIDTH=64 时) 201416016(DATAPATH_WIDTH=512 时) | 主机接口时钟频率。单位为 Hz |
APB_CLK_FREQ | 19531250(DATAPATH_WIDTH=64 时) 100000000(DATAPATH_WIDTH=512 时) | APB 接口时钟频率。单位为 Hz |
PTP_CLK_FREQ | 100446545 | PTP 接口时钟频率。单位为 Hz。范围为 95MHz 到 105MHz |
UUID[127:0] | 128’h889B7CE3_65A5_4247_8B05_4FF1904C3359(Lattice LF-SNSR-ETH-EVN) 128’hED6A9292_DEBF_40AC_B603_A24E025309C1(Microchip MPF200-ETH-SENSOR-BRIDGE) 128’hF1627640_B4DC_48AF_A360_C65B09B3D230(Leopard Imaging VB1940 Eagle Camera) 128’h9957A9AC_36B5_4518_83EC_5D514AECB750(TauroTech DA326) | 通用唯一标识符,用于识别板卡以获取和远程刷写正确的比特流文件 |
ENUM_EEPROM | 已定义或未定义 | 定义时,从外部非易失性存储器读取枚举包内容。未定义时,使用以下定义的宏 |
EEPROM_REG_ADDR_BITS | 8 或 16 | ENUM_EEPROM 定义时有效。EEPROM 中使用的寄存器地址位数 |
DATAPATH_WIDTH | 8, 16, 32, 64, 128, 256, 512, 1024 | 传感器 AXI Stream TDATA 的位宽。该数值必须按字节对齐,即必须能被 8 整除 |
DATAKEEP_WIDTH | DATAPATH_WIDTH/8 | 传感器 AXI Stream TKEEP 的位宽。不应更改 |
DATAUSER_WIDTH | 1-2 | 传感器 AXI Stream TUSER 信号的位宽 |
SENSOR_RX_IF_INST | 未定义, 1-32 | 传感器 RX 接口数量 |
SIF_RX_WIDTH[SENSOR_RX_IF_INST-1:0] | 8, 16, 32, 64, 128, 256, 512, 1024 | SENSOR_RX_IF_INST 定义时有效。每个传感器 RX 接口宽度可单独定义。最大值应为 DATAPATH_WIDTH |
SIF_RX_DATA_GEN | 未定义, 已定义 | SENSOR_RX_IF_INST 定义时有效。实例化数据生成器模块以测试传感器到主机数据路径 |
SIF_RX_PACKETIZER_EN[SENSOR_RX_IF_INST-1:0] | 0, 1 | SENSOR_RX_IF_INST 定义时有效。每个传感器 RX 接口的封装器可单独启用 |
SIF_RX_VP_COUNT[SENSOR_RX_IF_INST-1:0] | 请勿修改 | SENSOR_RX_IF_INST 和 SIF_RX_PACKETIZER_EN 定义时有效。待定义。请勿更改 |
SIF_RX_SORT_RESOLUTION[SENSOR_RX_IF_INST-1:0] | 请勿修改 | SENSOR_RX_IF_INST 和 SIF_RX_PACKETIZER_EN 定义时有效。待定义。请勿更改 |
SIF_RX_VP_SIZE[SENSOR_RX_IF_INST-1:0] | 请勿修改 | SENSOR_RX_IF_INST 和 SIF_RX_PACKETIZER_EN 定义时有效。待定义。请勿更改 |
SIF_RX_NUM_CYCLES[SENSOR_RX_IF_INST-1:0] | 请勿修改 | SENSOR_RX_IF_INST 和 SIF_RX_PACKETIZER_EN 定义时有效。待定义。请勿更改 |
SENSOR_TX_IF_INST | 未定义, 1-32 | 传感器 TX 接口数量 |
SIF_TX_WIDTH[SENSOR_TX_IF_INST-1:0] | 8, 64, 512 | SENSOR_TX_IF_INST 定义时有效。每个传感器 TX 接口宽度可单独定义。最大值应为 DATAPATH_WIDTH |
SIF_TX_BUF_SIZE[SENSOR_TX_IF_INST-1:0] | 1024, 2048, 4096 | SENSOR_TX_IF_INST 定义时有效。设置传感器 TX 缓冲区大小 |
HOST_WIDTH | 8, 16, 32, 64, 128, 256, 512 | 主机 AXI Stream TDATA 的位宽。该数值必须按字节对齐,即必须能被 8 整除 |
HOSTKEEP_WIDTH | HOST_WIDTH/8 | 主机 AXI Stream TKEEP 的位宽。不应更改 |
HOSTUSER_WIDTH | 1 | 主机 AXI Stream TUSER 信号的位宽 |
HOST_IF_INST | 1-32 | 主机接口数量 |
HOST_MTU | 1500, 4096 | 以太网包大小,单位为字节 |
SPI_INST | 未定义, 1-8 | SPI 接口数量 |
I2C_INST | 未定义, 1-8 | I2C 接口数量 |
UART_INST | 未定义, 1 | UART 接口数量 |
GPIO_INST | 1-255 | GPIO 输入和输出位数 |
GPIO_RESET_VALUE[GPIO_INST-1:0] | 0 | GPIO 位的复位值 |
REG_INST | 1-8 | 用户寄存器数量 |
N_INIT_REG | 未定义, 整数值 | 初始化寄存器数量 |
构建版本(Build Revision)
参数 BUILD_REV[47:0] 可传递到 “HOLOLINK_top” 模块,以唯一标识 FPGA 构建版本。
传感器接口配置
在 HSB IP 连接多个具有不同带宽的传感器的应用中,IP 可以按每个传感器接口进行配置以优化资源利用率。
DATAPATH_WIDTH 参数定义所有传感器接口的 AXI Stream 向量宽度以简化集成,应设置为与最宽的传感器匹配。SIF_RX_WIDTH 和 SIF_TX_WIDTH 参数可单独配置,以指定每个传感器接口的更窄数据宽度。
例如,如果第一个传感器接口宽度为 64 位,第二个为 32 位:将 DATAPATH_WIDTH 设置为 64,将 SIF_RX_WIDTH 设置为 {32, 64}。对于第二个传感器接口,仅使用 AXI Stream TDATA 的 [31:0] 和 AXI Stream TKEEP 的 [3:0],其余信号应连接到 0。AXI Stream TKEEP 的最低有效位 [3:0] 仍需设置为全 1’b1。
此外,当向 Thor 流式传输相机数据时需要的**封装器(Packetizer)**功能,可以按每个传感器接口启用。例如,如果第一个传感器需要封装器功能而第二个不需要,将 SIF_RX_PACKETIZER_EN 参数设置为 {0,1}。
HSB IP 支持虚拟端口映射。更多信息请参阅 传感器接口到虚拟端口映射。
BOOTP 包
HSB IP 在每个主机接口上传输广播 BOOTP 请求包(遵循 RFC-951)。BOOTP 请求包用于将 HSB 枚举到主机,并在多板枚举情况下从默认 IP 地址更改 IP 地址。HSB IP 的默认 IP 地址为:主机接口 0 为 “192.168.0.2”,主机接口 1 为 “192.168.0.3”,依此类推。BOOTP 请求包每秒发送一次。如果 HSB IP 内部使用 PTP,BOOTP 包在每次**每秒脉冲(PPS)**时发送,PPS 在 i_ptp_clk 域内部生成。如果定义了 EXT_PTP 宏,则当 i_ptp_sec 输入端口的最低有效位切换时,内部生成 PPS。
BOOTP 包的**厂商字段(Vendor Field)**用于向主机通信枚举信息和 HSB 状态。BOOTP 厂商字段布局如下表:
表 2
| 字节编号 | 描述 | 值 |
|---|---|---|
| [0] | 厂商标签 | 0xE0 |
| [1] | 标签长度 | 0x38 |
| [5:2] | ASCII “NVDA” | 0x4144564E,大端格式 |
| [6] | 以太网端口号 | 0x0 表示端口 0,0x1 表示端口 1 |
| [7] | 枚举版本 | 0x2 |
| [9:8] | 保留 | 保留。设为 0 |
| [25:10] | UUID | HOLOLINK_def.svh 中定义的 UUID。大端格式 |
| [29:26] | 保留 | 保留 |
| [36:30] | 板卡序列号 | 从 EEPROM 获取或从 HSB IP 输入端口获取的 BOARD_SN。小端格式 |
| [38:37] | Holoscan Sensor Bridge IP 版本 | 0x2606 对应 Holoscan SDK v2.7.0 版本。小端格式 |
| [44:39] | 保留 | 保留 |
| [54:45] | PTP 时间戳 | PTP 时间戳。秒和纳秒,PTP v2 格式。大端格式 |
| [56:55] | 包序列号 | 包序列号。每发送一个 BOOTP 包递增。大端格式 |
| [57] | 状态 | 当 HSB 中启用 PTP 且已接收到 SYNC PTP 包时为 0x1 |
| [63:58] | 保留 | 保留。设为 0 |
以下进一步解释用于枚举包的每个宏。
UUID:此宏定义板卡的唯一标识符。Holoscan 使用此值来识别正在交互的板卡,并获取正确的比特流文件进行远程刷写。对于新开发的板卡,用户可以生成并分配新的 UUID。此宏必须定义,不能可选地存储在非易失性存储器中。
ENUM_EEPROM:定义此宏时,枚举字段、MAC 地址和板卡序列号在启动时从板载非易失性存储器获取。枚举字段通过 I2C 端口 0 获取,EEPROM 7 位地址为 0x50。
使用 Holoscan Sensor Bridge IP 的板卡批量生产需要外部 EEPROM 来存储唯一的 MAC 地址和板卡序列号。使用评估平台进行测试和启动时,枚举字段、MAC 地址和板卡序列号可以通过输入端口传递给 HSB IP。
从 EEPROM 获取时,MAC 地址和板卡序列号必须放置在这些 EEPROM 寄存器地址中。
| EEPROM 地址(十进制) | MAC 位 |
|---|---|
| 68 | MAC[47:40] |
| 69 | MAC[39:32] |
| 70 | MAC[31:24] |
| 71 | MAC[23:16] |
| 72 | MAC[15:8] |
| 73 | MAC[7:0] |
| 74 | Board SN[55:48] |
| 75 | Board SN[47:40] |
| 76 | Board SN[39:32] |
| 77 | Board SN[31:24] |
| 78 | Board SN[23:16] |
| 79 | Board SN[15:8] |
| 80 | Board SN[7:0] |
系统初始化
Holoscan Sensor Bridge IP 提供系统初始化功能,在上电时向寄存器写入数据。该功能用于初始化以太网模块,以建立 FPGA 与主机之间的以太网连接,也可用于顶层设计中的任何其他用户功能。
待初始化的寄存器列表在 “HOLOLINK_def.svh” 中定义为 init_reg 数组。init_reg 是一个非打包数组,尺寸为 [N_INIT_REG] [63:0],其中 N_INIT_REG 宏定义了待初始化寄存器的数量,64 位向量用于定义寄存器的 32 位地址([63:32])和 32 位写入数据([31:0])。
init_reg 数组条目示例如下:
{32'h1000_0020, 32'h0000_00FF} // init_reg[0]
将向用户 REG_INST_0 模块的地址偏移 0x0000_0020 写入数据 0x0000_00FF。
系统初始化完成后,o_init_done 端口将在 i_apb_clk 时钟域中被置为高电平。用户可以使用该信号来门控依赖以太网模块初始化的逻辑。
12. 仿真启动 | Holoscan Sensor Bridge 文档
仿真启动允许用户检查 Holoscan Sensor Bridge IP 的实例化和端口连接。需要进行以下修改,才能使 HSB IP 进入配置状态,并通过主机 TX 接口流式传输传感器数据。
-
注释掉 “HOLOLINK_def.svh” 中的
define ENUM_EEPROM在硬件中,当
ENUM_EEPROM被定义时,Holoscan Sensor Bridge IP 通过 I2C 读取外部 EEPROM 以获取唯一的 MAC 地址和枚举数据。但这需要在仿真测试平台中提供 EEPROM 的总线功能模型(Bus Functional Model)。当ENUM_EEPROM未定义时,MAC 地址和板卡序列号可以作为输入端口传递给 HSB IP。 -
初始化 HSB IP 以进行数据平面流式传输
在硬件中,软件 API 配置 Holoscan Sensor Bridge IP 以在主机 TX 接口上进行数据平面流式传输。在仿真中,用户可以使用 “HOLOLINK_def.svh” 中的
init_reg在复位后配置 Holoscan Sensor Bridge IP。
以下是可以添加到 init_reg 中以初始化以太网端口 0 的寄存器列表。一旦传感器 RX AXI-S 接口被驱动了 HOST_MTU 字节或更多数据,Holoscan Sensor Bridge IP 将在主机 TX 接口上驱动数据平面流。
//地址 数据
{32'h0200_0304, 32'h0000_000B}, // dp_pkt_0 , dp_pkt_len
{32'h0200_0308, 32'h0000_12B7}, // dp_pkt_0 , dp_pkt_host_udp_port
{32'h0200_030C, 32'h0000_0001}, // dp_pkt_0 , dp_pkt_vip_mask
{32'h0000_1020, 32'h0000_600D}, // sif_0 , dp_pkt_mac_addr_lo
{32'h0000_1024, 32'h0000_0000}, // sif_0 , dp_pkt_mac_addr_hi
{32'h0000_1028, 32'h0000_BEEF}, // sif_0 , dp_pkt_ip_addr
{32'h0000_102C, 32'h0000_3000}, // sif_0 , dp_pkt_fpga_udp_port
{32'h0000_1000, 32'h0000_0000}, // sif_0 , Destination QP
{32'h0000_1004, 32'h0000_F00D}, // sif_0 , Remote Key
{32'h0000_1008, 32'h0000_0000}, // sif_0 , Buffer 0 Virtual Address
{32'h0000_1018, 32'h0001_0000}, // sif_0 , Bytes per Window
{32'h0000_101C, 32'h0000_0001}, // sif_0 , Buffer Enable
{32'h0200_0108, 32'h0000_0064}, // eth_pkt_0 , Eth pkt data plane priority
上述示例针对 1 条数据路径。对于额外的数据路径:
- 向 dp_pkt 寄存器地址添加偏移 “0x0001_0000”,向 sif 寄存器地址添加偏移 “0x0000_0040”。
- 在 Holoscan Sensor Bridge IP HIF TX/RX 接口端口中实例化第 2 条或更多数据路径。
- 将
N_INIT_REG增加所添加的初始化寄存器数量。
13. 硬件调试 | Holoscan Sensor Bridge 文档
有几种方法可用于在硬件中调试 Holoscan Sensor Bridge,以缩小问题范围。
数据生成器(Data Generator)
Holoscan Sensor Bridge IP 内部有一个传感器数据生成器,用于驱动传感器 RX 接口信号。启用传感器数据生成器可以测试从内部传感器 RX 到主机 TX 数据平面的路径,以验证 RoCE/CoE 配置是否正确以及主机 TX 路径是否正确集成。启用数据生成器的步骤:
- 在 “HOLOLINK_def.svh” 中添加
\define SIF_RX_DATA_GEN` - 将以下代码添加到 Python 脚本中,并在设置接收器后调用该函数。
CODE_SPAN_0
包序列号(PSN)寄存器
包序列号寄存器用于统计 Holoscan Sensor Bridge 各数据平面流量中的包数量。
传感器接口(SIF)TVALID 计数器:SIF TVALID 计数器寄存器在 i_sif_axis_tvalid 置位的每个时钟周期递增。如果该寄存器未递增,请检查驱动程序和与 i_sif_axis_tvalid 端口的连接。
传感器接口帧起始(SOF)PSN:帧起始被认为是 i_sif_axis_tlast 置位后第一个 i_sif_axis_tvalid && o_sif_axis_tready 的周期。在相机应用中,i_sif_axis_tlast 在帧结束时置位。如果该寄存器未递增,请检查 SIF TVALID 计数器是否递增以及 i_sif_axis_tlast 是否正确置位。如果这些信号正确置位,Holoscan Sensor Bridge 的 o_sif_axis_tready 可能卡在低电平,这可能表明主机数据平面流量处于卡死状态。
主机数据平面 PSN:一旦接收到足够的传感器数据以发送由可配置寄存器指定大小的以太网包,传感器数据将被 CoE 或 RoCE 头部封装,并通过主机 TX 接口传输。每个数据平面主机包按递增编号。如果该寄存器未递增,可能是没有传感器数据驱动到 Holoscan Sensor Bridge IP,或者 CoE/RoCE 配置未正确设置以传输数据。
CODE_SPAN_1
外设调试
SPI 和 I2C 控制器提供状态寄存器以帮助调试通信问题。
状态寄存器监控:监控 STATUS 寄存器(SPI 偏移 0x0300_0080,I2C 偏移 0x0300_0280)。
对于 SPI 和 I2C 控制器:
- BUSY(位 0):1 = 事务进行中,0 = 空闲
- FSM_ERR(位 1):配置错误(例如,无效字节数)
- DONE(位 4):事务成功完成
I2C 附加状态位
- ARB_LOST(位 2):仲裁丢失(多主设备)
- NACK(位 3):从设备发送否定确认
常见问题及调试步骤
-
事务未启动
- 检查 CONTROL.START 位是否已设置
- 验证 BUS_EN 寄存器是否选择了正确的设备
- 监控 BUSY 位从 0 到 1 的转换
-
事务卡在 BUSY 状态
- 检查 FSM_ERR 位是否有配置错误
- 验证字节计数寄存器是否有效
- 对于 I2C:检查设备地址和超时设置
- 对于 SPI:检查 SPI_MODE 和 PRESCALER 配置
-
通信故障
- I2C NACK:验证设备地址和电源
- I2C ARB_LOST:检查总线争用
- SPI 数据问题:验证 SPI_MODE 和时钟频率
- 所有情况:使用示波器检查信号完整性
UART 调试寄存器
使用基地址 0x0300_0400 的 UART 状态和调试寄存器来隔离 RX/TX 路径问题:
- STATUS0 (0x0300_0480):
- TX_BUSY(位 0) / RX_BUSY(位 1):活动指示器
- TX_FIFO_EMPTY(位 3) / RX_FIFO_NOT_EMPTY(位 5):FIFO 流状态
- RX_PARITY_ERROR(位 6)、RX_FRAME_ERROR(位 7)、TX_OVERFLOW(位 8)、RX_OVERFLOW(位 9)、RX_GLITCH_ERROR(位 13):粘性错误位
- LAST_RX_VALID(位 10):指示
LAST_RX包含有效数据
- STATUS1 (0x0300_0484):
- TX 空/几乎满/几乎空、RX 非空和 RX 毛刺错误的粘性中断状态
- LAST_RX (0x0300_0548):
- 从
RX_DATA消耗的最近字节的非破坏性视图
- 从
通过 CTRL3 (0x0300_040C) 清除粘性中断/错误条件,并通过 CTRL0[10] (0x0300_0400) 清除 LAST_RX_VALID。
14. 已知限制 | Holoscan Sensor Bridge 文档
-
Holoscan Sensor Bridge IP 支持单条和块 32 位读写 ECB 命令。
-
Holoscan Sensor Bridge IP 不支持快速连续的 ICMP(或 PING)请求。连续 ping 之间的时间间隔应 >= 1ms。
-
传感器 RX AXI-Stream 的 TKEEP 信号未被使用。这意味着当 TVALID 为高时,TDATA 的所有字节都是有效的。
-
主机 TX 和 RX AXI-Stream 仅在 TLAST 为高时支持 TKEEP 不全为 1 的情况。当 TLAST 为低时,TKEEP 必须全为 1。
15. Holoscan Sensor Bridge FPGA 固件更新
Holoscan Sensor Bridge(HSB)FPGA 固件可以通过以太网远程刷写。
-
按照 设置说明 构建并运行演示容器。以下所有命令均在演示容器内运行。
-
使用 ping 命令检查与传感器桥接板的连接:
$ ping 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.143 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.098 ms 64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.094 ms如果您的系统已将 192.168.0.0/24 网络用于其他用途,请参阅 配置传感器桥接设备使用的 IP 地址 的说明。重新配置地址后,请确保您可以在预期地址 ping 通设备。
-
这些说明假设您的 FPGA 已加载 0x2412 或更新版本的固件;这是 HSB 2.0 中包含的版本。如果您的配置较旧,请先按照 更新到 2.0 的说明 操作。要查看您的 HSB 配置的 FPGA IP 版本:
hololink-enumerate此命令将显示从 HSB 的 BOOTP 枚举消息接收到的数据,其中包括 HSB IP 版本。
HSB 刷写器(HSB Flasher)
hsb_flasher 工具提供了一个通用入口点,用于通过以太网向 HSB 设备提供板卡特定的固件刷写机制。它将已知工具(如 program_lattice_cpnx100 和 program_leopard_cpnx100)聚合到单个命令中,自动识别连接的设备并选择适当的刷写策略。
支持的设备
- Lattice CPNX100-ETH-SENSOR-BRIDGE
- Leopard Imaging VB1940 Eagle Camera
- Microchip MPF200-ETH-SENSOR-BRIDGE
- TauroTech DA326
快速入门
-
验证与传感器桥接板的网络连接:
ping 192.168.0.2 -
将设备刷写到最新的可用固件版本:
hsb_flasher --hololink 192.168.0.2该工具自动从清单中选择发现的设备的最新固件版本。要定位特定版本(十六进制,不带
0x前缀),使用--target-version:hsb_flasher --hololink 192.168.0.2 --target-version 2603如果设备已运行目标版本,工具将退出并显示无需更新的消息。要强制重新刷写相同版本(例如,当固件构建被相同版本号的新构建取代时),使用
--reapply:hsb_flasher --hololink 192.168.0.2 --reapply -
刷写完成后,重新上电设备。
-
通过 ping 设备并再次运行
hololink-enumerate来验证更新,确认新的固件版本。
详细说明
在 快速入门 所示的正常使用中,hsb_flasher 执行以下步骤:
-
设备发现 — 工具监听 BOOTP 枚举消息。枚举数据中,当前固件版本(
hsb_ip_version)和 FPGA UUID(fpga_uuid)最为相关。 -
清单选择 — 枚举响应中的 FPGA UUID 用于查找匹配的 YAML 清单。工具扫描
firmware_information/目录中的所有.yaml文件,并选择其fpga_uuid字段与发现的设备匹配的文件。每个 YAML 清单描述特定的板卡类型,并列出可用的固件版本及其下载 URL、预期文件大小和 MD5 校验和。 -
版本选择 — 如果提供了
--target-version,则直接使用该版本。否则,工具扫描清单并自动选择最高的可用版本号。如果设备已在目标版本,工具将提前退出,除非指定了--reapply。 -
固件获取 — 在匹配的 YAML 清单中查找目标版本条目,以确定所需的固件文件(取决于板卡,可能需要 CLNX 和/或 CPNX)。如果固件文件托管在远程,则通过 HTTPS 下载并验证预期大小和 MD5 校验和。YAML 中也可以指定本地路径。
-
刷写策略选择 — 工具扫描
firmware_flash_strategies/目录中的 Python 模块,并通过调用每个模块的supports(fpga_uuid, version)函数来查询,传入设备的 FPGA UUID 和当前固件版本。第一个返回true的模块被选中。每个策略模块将设备版本映射到特定的 C++ 刷写例程(通过 pybind11 暴露),该例程知道如何对该板卡进行编程。 -
刷写执行 — 调用所选策略的
do_flash()函数,传入固件文件路径。底层 C++ 刷写例程通过 Hololink 核心库连接到设备并执行刷写。
刷写完成后,设备必须重新上电才能使新固件生效。
直接模式(Direct Mode)
直接刷写模式允许从本地文件刷写固件,绕过内置的 YAML 清单查找和固件下载。设备发现和刷写策略选择仍正常操作:工具连接到设备,读取其 FPGA UUID 和固件版本,并使用这些在 firmware_flash_strategies/ 中查找匹配的 Python 模块。与标准模式的唯一区别是固件文件来自您的本地路径,而不是通过 YAML 清单解析和获取。
仅使用 CPNX 镜像刷写(例如 HSB Leopard):
hsb_flasher -H 192.168.0.2 --bitfile /path/to/cpnx.bit
同时使用 CLNX 和 CPNX 镜像刷写(例如 HSB Lite):
hsb_flasher -H 192.168.0.2 --clnx /path/to/clnx.bit --bitfile /path/to/cpnx.bit
默认情况下,刷写策略使用设备在发现期间报告的固件版本进行选择。要覆盖此设置(例如,当设备运行无法识别的版本时强制使用特定刷写例程),使用可选的 --flash-version 参数,传入十六进制版本字符串(不带 0x 前缀):
hsb_flasher -H 192.168.0.2 --bitfile /path/to/cpnx.bit --flash-version 2507
自定义镜像
可以通过提供两个文件来添加对新 FPGA 板卡的支持:YAML 固件清单和 Python 刷写策略模块。在运行时,hsb_flasher 通过扫描可执行文件旁边的 firmware_information/ 和 firmware_flash_strategies/ 目录自动发现两者。
固件清单(YAML)
在 firmware_information/ 目录中创建新的 .yaml 文件。文件必须包含目标板卡的 FPGA UUID 和固件版本列表,包括其下载位置、MD5 校验和及文件大小。
fpga_uuid:
- <your-fpga-uuid>
firmware_versions:
- version: 0x2603
cpnx:
- location: https://example.com/firmware/cpnx_v2603.bit
md5: <md5-checksum>
size: <file-size-in-bytes>
clnx:
- location: https://example.com/firmware/clnx_v2603.bit
md5: <md5-checksum>
size: <file-size-in-bytes>
fpga_uuid 字段是 YAML 序列;单个 UUID 使用单元素列表。仅在板卡需要时包含 clnx 条目;仅需要 CPNX 固件的板卡(如 HSB Leopard)可以完全省略 clnx 字段。
location 字段可以是 HTTPS URL(固件将被下载并缓存)或本地文件路径。
刷写策略模块(Python)
在 firmware_flash_strategies/ 目录中创建新的 .py 文件。模块必须暴露两个顶层函数供 hsb_flasher 调用:
-
supports(fpga_uuid, version)— 如果此模块可以刷写给定 FPGA UUID 在给定固件版本下的设备,则返回True。 -
do_flash(fpga_uuid, version, mac_address, ip_address, clnx_path, cpnx_path)— 执行刷写操作。成功返回True,失败返回False。
每个子类声明一个 MIN_VERSION(其覆盖版本范围的下限,包含);版本为 V 的设备将路由到具有最大 MIN_VERSION <= V 的策略。新的次要修订版自动路由 — 只需更新 YAML 清单。新的刷写协议意味着添加具有适当 MIN_VERSION 的新类。
最小刷写策略模块遵循以下模式:
from abc import ABC, abstractmethod
from typing import Optional
class MyBoardFlasherBase(ABC):
FPGA_UUID = "<your-fpga-uuid>"
MIN_VERSION: int = 0 # 子类设置此值
def __init__(self, ip_address: str, mac_address: str, version: int):
self.ip_address = ip_address
self.mac_address = mac_address
self.version = version
@classmethod
def supports(cls, fpga_uuid: str, version: int) -> bool:
return fpga_uuid == cls.FPGA_UUID and version >= cls.MIN_VERSION
@abstractmethod
def flash(self, clnx_path: str, cpnx_path: str) -> bool:
pass
class MyBoardFlasherModern(MyBoardFlasherBase):
MIN_VERSION = 0x2603
def flash(self, clnx_path: str, cpnx_path: str) -> bool:
# 在此处实现板卡特定的刷写逻辑。
# 通常调用 pybind11 C++ 模块来执行 SPI 操作。
...
# 按 MIN_VERSION 降序排列
FLASH_STRATEGIES = sorted(
[MyBoardFlasherModern],
key=lambda c: c.MIN_VERSION,
reverse=True,
)
def supports(fpga_uuid: str, version: int) -> bool:
return any(cls.supports(fpga_uuid, version) for cls in FLASH_STRATEGIES)
def get_flasher(fpga_uuid: str, version: int,
ip_address: str, mac_address: str) -> Optional[MyBoardFlasherBase]:
for cls in FLASH_STRATEGIES:
if cls.supports(fpga_uuid, version):
return cls(ip_address=ip_address, mac_address=mac_address, version=version)
return None
def do_flash(fpga_uuid: str, version: int, mac_address: str, ip_address: str,
clnx_path: str, cpnx_path: str) -> bool:
flasher = get_flasher(fpga_uuid, version, ip_address, mac_address)
if flasher is None:
return False
return flasher.flash(clnx_path, cpnx_path)
每个策略类中的 flash() 方法包含板卡特定的编程逻辑。现有实现使用 pybind11 C++ 模块,通过 Hololink 核心库执行 SPI 擦除/编程/验证操作。请参阅 flash_tools/hsb_lite/ 和 flash_tools/hsb_leopard/ 中的参考实现。
旧版脚本
以下脚本是 hsb_flasher 内部用于 Lattice、Leopard Imaging 和 Microchip 设备的底层工具。它们在仓库中可用于参考或高级用途:
program_lattice_cpnx100— 位于build/tools/program_lattice_cpnx100/program_leopard_cpnx100— 位于build/tools/program_leopard_cpnx100/polarfire_esb.py— 位于build/python/lib/hololink/tools/

186

被折叠的 条评论
为什么被折叠?



