AMD/Xilinx 生态中的块级控制协议(Block-Level Control Protocol),以cmac 为例
ap_ctrl_none是 AMD/Xilinx Vitis/Vivado HLS 生态中的块级控制协议(Block-Level Control Protocol),表示该硬件模块为**“自由运行”(Free-Running)**模式——一旦 FPGA 加载完成,模块即刻自主运转,无需 Host CPU 通过ap_start/ap_done等握手信号来逐次调度。
一、三种块级控制协议对比
在 Vitis HLS 或 RTL Kernel 中,块级协议决定整个 IP 核的执行生命周期(何时启动、何时算完成、何时空闲),与端口级的 AXI4-Stream/AXI4-Lite 等数据接口是不同层面的概念 :
| 协议 | 控制信号 | 执行模式 | 典型场景 |
|---|---|---|---|
| ap_ctrl_hs | ap_start,ap_done,ap_idle,ap_ready | 控制驱动,单次执行,Host 发令 → 核执行 → 核报告完成 | 传统加速器(如 FFT、矩阵乘) |
| ap_ctrl_chain | 上述信号 +ap_continue | 控制驱动,支持流水线级联,下游可反压上游 | 多核链式数据流 |
| ap_ctrl_none | 无握手信号(或被优化为高电平常有效) | 数据驱动,持续运行 | 网络包转发、视频流、自由运行 RTL Kernel |
二、ap_ctrl_none 的核心语义
1. 无生命周期握手
模块不暴露ap_start/ap_done/ap_idle/ap_ready给 Host。对 Host 软件(XRT/OpenCL)而言,无法通过clEnqueueTask来"启动"一次任务,也无法查询"这次任务是否做完" 。
2. 数据驱动(Data-Driven)
模块的运行节奏完全由数据流可用性决定:
- 输入端口(如
S_AXIS)有数据 → 模块处理; - 输入为空 → 模块自动阻塞(stall)等待;
- 输出端口(如
M_AXIS)被下游反压 → 模块自动挂起。
这相当于硬件层面的while(1)循环 。
3. 上电即运行
在 RTL Kernel 语境下,一旦xclbin加载到 FPGA,ap_ctrl_none的内核立即开始工作,不需要 Host 下发启动命令 。
三、为什么 CMAC Kernel 使用 ap_ctrl_none
结合 CMAC Kernel 文档,该设计选择ap_ctrl_none的原因非常明确:
| 设计特征 | 与 ap_ctrl_none 的契合点 |
|---|---|
| 网络子系统 | 100G 以太网 MAC/PCS 是持续收发的流水线,没有"一次任务"的概念 |
| AXIS 数据流 | 通过S_AXIS/M_AXIS与上下游交互,天然适合数据驱动 |
| 控制与数据分离 | 数据面(512-bit AXIS)持续跑;控制面(AXI4-Lite 寄存器)旁路配置,互不影响 |
| 无需 Host 调度 | Host 不需要说"发一个包"——包来了硬件自动处理 |
换句话说,CMAC 是一个**“永远在线"的 I/O 引擎**,而非"被 Host 反复调用的函数”。
四、使用 ap_ctrl_none 的约束与注意事项
根据 AMD 官方文档,采用该协议需满足特定条件,否则 C/RTL 协同仿真会报错 :
- 必须是流式/流水线设计:接口推荐使用
hls::stream或axis,避免使用m_axi(内存映射)作为数据主通路; - 不能有循环内的 dataflow 区域:
ap_ctrl_none区域若嵌套在for循环内部,会导致父级 FSM 永远等不到ap_done而死锁; - 父级模块也需为 ap_ctrl_none:若上层还有非自由运行模块等待该核的完成信号,系统会挂起;
- AXI4-Lite 仍可用:虽然数据面无控制握手,但寄存器配置接口(
S_AXILITE)仍可独立存在,用于状态查询和参数配置。
五、总结
ap_ctrl_none=拉闸即运转,数据来则动,数据尽则停,Host 不干预生命周期。
对 CMAC 这类 100G 网络硬核而言,它是"自由运行内核"的标准签名,确保网卡从 FPGA 加载完成后即刻进入线速转发状态,无需 CPU 逐包调度。
六、cmac 概述
CMAC 内核
本文档提供 cmac 内核的概述。
cmac 内核
cmac内核是一个 RTL 自由运行内核,它封装了 UltraScale+ 集成 100G 以太网子系统。该内核使用ap_ctrl_none作为硬件控制协议。
该内核根据传递给 make 的INTERFACE、DEVICE和PADDING_MODE参数进行配置。它向用户逻辑暴露两个 512 位 AXI4-Stream 接口(S_AXIS 和 M_AXIS),这些接口以内核相同的频率运行;内核内部集成了 CDC(时钟域跨越)逻辑,用于将内核时钟转换为 100G 以太网子系统时钟。它还提供一个 AXI4-Lite 接口,用于查看 UltraScale+ 集成 100G 以太网子系统的寄存器映射。
UltraScale+ 集成 100G 以太网子系统
100G 以太网子系统提供了一个集成的 100 千兆比特每秒(Gbps)以太网媒体访问控制器(MAC)、物理编码子层(PCS)、IEEE 802.3bj 里德-所罗门前向纠错(RS-FEC)以及 100GE 自动协商/链路训练(AN/LT)IP,以支持 KR4、CR4、SR4、CWDM4、PSM4 或 ER4f 等高性能应用方案。
注意:自动协商/链路训练在此内核中未启用。
cmac_sync
该 IP 实现了 PG203 中描述的内核启动序列。
frame_padding
该 IP 实现可选的帧填充至 60 或 64 字节。填充模式在编译时通过PADDING_MODE参数设置,具体如下:模式0表示不填充,模式1(默认)填充至 60 字节,模式2填充至 64 字节。
时钟域跨越
UltraScale+ 集成 100G 以太网子系统中的 Rx 和 Tx AXI4-Stream 接口工作在 322.265625 MHz。为了适应设计中其余部分的不同频率,在 Tx 路径(acc_kernel_tx_cdc 和 fifo_cmac_tx)和 Rx 路径(fifo_cmac_rx_cdc)中均包含了跨时钟域逻辑。
寄存器映射
UltraScale+ 集成 100G 以太网子系统的寄存器映射(详见 PG203)可通过 AXI4-Lite 接口访问。其中许多寄存器已通过 template.xml 文件方便地映射为内核参数。
如果您希望访问未映射的寄存器,可以使用 pynq MMIO 的读写方法。
例如:
# 读取 CONFIGURATION_AN_ABILITY 寄存器cmac.read(0xA8)# 在 CONFIGURATION_AN_ABILITY 寄存器中设置 ctl_an_ability_1000base_kxcmac.write(0xA8,0x1)您也可以修改 template.xml 文件以添加更多寄存器。修改此文件时需谨慎,确保 id 正确更改。一旦修改了 template.xml 文件,您必须重新构建设计,以便将这些更改包含到 xclbin 中。修改 template.xml 后,请删除此文件夹中的所有 *.xo 文件。
接口
| 名称 | 描述 |
|---|---|
| ap_clk | 主时钟 |
| ap_rst_n | 主低电平复位 |
| clk_gt_freerun | 自由运行内核时钟 |
| gt_ref_clk | GT 参考时钟 |
| gt_serial_port | GT 串行通道 |
| S_AXILITE | AXI4-Lite 从属控制接口 |
| S_AXIS | 512 位 AXI4-Stream 发送接口 |
| M_AXIS | 512 位 AXI4-Stream 接收接口 |
多路 100 GbE 接口与 Alveo 卡
为了支持多路 100 GbE 接口和 Alveo 卡,会生成略有不同的内核,其内部结构和接口保持不变。但 UltraScale+ 集成 100G 以太网子系统的配置会根据每个接口和 Alveo 卡进行调整。这些配置详见 此处。
许可证
要生成使用 UltraScale+ 集成 100G 以太网子系统 的 xclbin 文件,您需要有效的许可证。您可以按照这些步骤生成免费许可证。
注意:要启用自动协商/链路训练,您需要单独的许可证。更多信息请参阅相关文档。
修改 RS-FEC
RS-FEC 在 CMAC 实例中默认启用。在运行时,RS-FEC 默认处于关闭状态,可以通过调用 Pynq 和 C++ 驱动程序中的相应函数来激活。激活后,RS-FEC 设置为子模式 1(纠错和指示均启用)。更多详情请参阅 UltraScale+ 集成 100G 以太网子系统 文档。
注意:RS-FEC 激活后会增加延迟。
Copyright© 2022 Xilinx