🏠

Versal 时钟设计教程管道 (Versal Clocking Tutorial Pipeline)

一句话概括

本模块是一个异构时钟域教学演示系统,展示了如何在 Versal ACAP 平台上将 AI Engine (AIE)、可编程逻辑 (PL) 和可编程逻辑 HLS 内核配置为不同的时钟频率,同时通过 AXI 流接口实现跨时钟域的无缝数据传输。该设计的核心是一个极坐标限幅 (Polar Clip) 内核,它实现了基于 CORDIC 算法的峰均比 (CFR) 降低处理,是 5G 基带信号处理中的典型运算。


问题空间与设计动机

异构计算的时钟挑战

在现代自适应计算平台(如 AMD Versal)中,一个典型的系统包含三类计算单元:

  1. AI Engine (AIE): 专为 DSP 优化的 SIMD 阵列,通常运行在 1GHz+
  2. 可编程逻辑 (PL): 传统 FPGA 逻辑,可根据时序约束灵活设置频率(通常 100-500MHz)
  3. 硬核处理器 (PS): ARM Cortex 核,管理控制流

核心问题: 当数据流经这些不同频率的域时,如何确保数据完整性吞吐匹配?简单的跨时钟域 (CDC) 电路可能引入亚稳态;而 FIFO 深度和流量控制设计不当会导致数据丢失或流水线停滞。

本模块解决的特定问题

本教程演示了以下工程决策:

  1. 多时钟配置: 将 s2mm 内核配置为 200MHz,而 polar_clip 内核配置为 100MHz,展示如何显式设置 freqhzfreqHz 参数
  2. 跨时钟域数据传输: 通过 AXI Stream 接口和 FIFO 缓冲实现 200MHz 域与 100MHz 域之间的可靠数据传递
  3. 算法到硬件的映射: 将复杂的 CORDIC 算法(用于计算复数幅值和相位)映射到 HLS 可综合代码,展示定点数优化和查找表技术
  4. 系统集成模式: 演示如何使用 .cfg 文件和 system.cfg 将多个 HLS 内核实例化并连接成完整的数据流水线

未选择的替代方案

  • 全局单一时钟: 简单但浪费功耗;200MHz 的 s2mm 无法被 100MHz 的 polar_clip 处理的数据填满,导致效率低下
  • 软核 CPU 处理: ARM 核可以执行 CORDIC 计算,但无法达到硬件并行所需的吞吐率(>100 MSamples/s)
  • 纯 RTL 实现: 性能更高但开发周期长;本设计使用 HLS 快速迭代算法优化

心智模型与核心抽象

工厂装配线类比

想象一条现代化的汽车装配线:

  • mm2s (Memory-to-Stream): 仓库的发货部门,从货架(DDR 内存)上取出零件,放到传送带上。这是一个数据源
  • 传送带 (AXI Stream): 连续流动的零件输送系统。关键特性是背压 (Backpressure):如果下游工位忙,传送带会暂停。
  • polar_clip (极坐标限幅工位): 一个精密加工站,执行复杂的测量和裁剪操作(CORDIC 算法)。这个工位比传送带慢(100MHz vs 200MHz),所以有一个缓冲区 (FIFO) 来缓冲零件。
  • AI Engine (AI 质检员): 负责检查中间产品并决定是否需要限幅(本教程中简化了,实际设计中 AIE 可能参与控制)。
  • s2mm (Stream-to-Memory): 仓库的收货部门,将成品从传送带卸下并存回货架。

关键洞察: 不同工位可以以不同速度运行,只要缓冲区足够深以吸收速度差异。系统设计者的任务是计算正确的缓冲区深度和流量控制策略。

时钟域与同步抽象

本模块引入了时钟域交叉 (CDC) 的核心概念:

  • 源时钟域 (Source Domain): 数据产生的时钟(如 s2mm 的 200MHz)
  • 目标时钟域 (Destination Domain): 数据消费的时钟(如 polar_clip 的 100MHz)
  • 同步器 (Synchronizer): 通常是一个多级触发器链(2-3 级),用于将控制信号从一个时钟域安全地传递到另一个时钟域,降低亚稳态概率
  • 异步 FIFO: 使用双端口 RAM 和独立的读写指针(格雷码编码)来实现跨时钟域的数据缓冲

本设计的 CDC 策略: 通过 AXI Stream 接口和 HLS 自动生成的 FIFO,实现 200MHz 到 100MHz 的可靠数据传输。


架构全景与数据流

高层架构图

flowchart LR subgraph PS["ARM 处理器子系统 (PS)"] HOST["主机应用程序
XRT/OpenCL"] end subgraph DDR["DDR 内存"] BUF_IN["输入缓冲区"] BUF_OUT["输出缓冲区"] end subgraph PL["可编程逻辑 (PL)"] subgraph CLK200["时钟域: 200MHz"] MM2S["mm2s
Memory-to-Stream
DMA 读取"] S2MM["s2mm
Stream-to-Memory
DMA 写入"] end subgraph CLK100["时钟域: 100MHz"] POLAR["polar_clip
极坐标限幅
CORDIC 算法"] end CDC1["跨时钟域
FIFO 缓冲"] CDC2["跨时钟域
FIFO 缓冲"] end subgraph AIE["AI Engine"] AIE_IN["DataIn1
输入接口"] AIE_OUT["DataOut1
输出接口"] end HOST -->|"配置/启动"| MM2S HOST -->|"配置/启动"| S2MM HOST -->|"配置"| POLAR MM2S <-->|"AXI4-Full
突发读取"| BUF_IN MM2S -->|"AXI4-Stream
连续数据"| AIE_IN AIE_IN -->|"AXI4-Stream"| CDC1 CDC1 -->|"AXI4-Stream
100MHz"| POLAR POLAR -->|"AXI4-Stream
100MHz"| CDC2 CDC2 -->|"AXI4-Stream
200MHz"| AIE_OUT AIE_OUT -->|"AXI4-Stream
连续数据"| S2MM S2MM <-->|"AXI4-Full
突发写入"| BUF_OUT S2MM -->|"中断/完成"| HOST style CLK200 fill:#e1f5fe style CLK100 fill:#fff3e0 style AIE fill:#f3e5f5

架构组件说明

1. PS (处理系统) - 指挥中枢 ARM 主机通过 XRT (Xilinx Runtime) 或 OpenCL API 与硬件交互。它的职责包括:分配 DDR 缓冲区、配置 DMA 寄存器、启动数据传输、轮询完成状态。在时钟教程的上下文中,主机还负责验证不同时钟频率下的数据完整性。

2. DDR 内存 - 数据湖 输入和输出缓冲区位于 PS 的 DDR 内存中。PL 的 DMA 引擎通过 AXI4-Full 接口以突发 (burst) 方式访问这些缓冲区,最大化内存带宽利用率。

3. mm2s / s2mm - DMA 引擎 (200MHz) 这两个 HLS 内核是标准的 Vitis 数据搬运器。mm2s 将 DDR 数据读取并转换为 AXI Stream;s2mm 执行相反操作。它们配置在 200MHz 时钟域,意味着它们可以以每时钟周期一个样本的速率处理数据(假设无背压)。

4. polar_clip - 信号处理核心 (100MHz) 这是本设计的关键差异化组件。它实现了峰值因子降低 (CFR) 算法中的极坐标限幅功能:

  • 接收复数样本 (I/Q)
  • 使用 CORDIC 算法计算幅值和相位
  • 如果幅值超过阈值 (CFR_THRESHOLD = 11626),则裁剪到阈值
  • 输出限幅后的复数样本

配置在 100MHz,是系统中最慢的组件,因此是吞吐瓶颈

5. AI Engine 接口 - 数据路由 AI Engine 在此教程中主要充当数据开关。它将 mm2s 的输出路由到 polar_clip,再将 polar_clip 的输出路由到 s2mm。这种架构允许在更复杂的系统中插入 AIE 的 DSP 处理,而本教程专注于 PL 侧的时钟配置。

6. 跨时钟域 (CDC) 逻辑 200MHz 和 100MHz 域之间的跨越由 HLS 自动生成的异步 FIFO 处理。这些 FIFO 使用独立的读写时钟,内部采用格雷码指针同步,确保即使在时钟频率不同的情况下也能可靠传输数据。


端到端数据流追踪

让我们追踪一个复数样本从输入到输出的完整旅程,理解时钟域如何交互。

初始化阶段 (主机侧)

  1. 缓冲区分配: 主机通过 xrt::bo (Buffer Object) 在 DDR 中分配输入和输出缓冲区
  2. 数据准备: 主机生成测试模式(如单音正弦波)并写入输入缓冲区
  3. 内核实例化: 主机加载 .xclbin 文件,获取 mm2ss2mmpolar_clip 的内核对象

数据传输阶段 (PL 侧)

周期 0-100: 预热阶段 (200MHz 域)

  • mm2s 从 DDR 读取 64 字节突发数据,填充其内部 AXI Stream 输出 FIFO
  • 数据通过 AIE 接口路由,到达 200MHz→100MHz 的跨时钟域 FIFO
  • 关键时序: 由于 200MHz 是 100MHz 的两倍,mm2s 每 5ns 产生一个样本,而 polar_clip 每 10ns 消费一个样本

周期 101-500: 稳态处理 (双时钟域)

  • polar_clip (100MHz):

    • T0: 读取输入样本 (I=16位, Q=16位,打包为 32 位)
    • T1: 计算 value_real_sq = value_real * value_real (整数乘法)
    • T2: 计算 value_imag_sqmag_sq = value_real_sq + value_imag_sq
    • T3: 调用 cos_sin_mag() (CORDIC 迭代,6 步旋转)
    • T4-T9: CORDIC 计算幅值、余弦、正弦
    • T10: 比较 mag_sqCFR_THRESHOLD*CFR_THRESHOLD
    • T11: 如果超限,计算裁剪值: res_real = cs_fixed_real * (magout - CFR_THRESHOLD)
    • T12: 打包输出: out_x.data = (real & 0xFFFF) | ((imag & 0xFFFF) << 16)
    • T13: out_sample.write(out_x)
  • 背压处理: 由于 polar_clip 需要 13 个周期处理一个样本(假设无流水线),而 mm2s 每周期可以输出一个样本,跨时钟域 FIFO 必须足够深(通常 16-32 项)以吸收这种速率不匹配。当 FIFO 满时,背压信号传播回 mm2s,暂停其读取。

周期 501+: 收尾阶段

  • 当所有输入样本处理完毕,mm2s 发送 TLAST 信号
  • polar_clip 将剩余样本冲刷 (flush) 到输出
  • s2mm 接收数据并写回 DDR,发送中断通知主机

关键时序参数

参数 说明
mm2s 时钟 200MHz 周期 5ns
s2mm 时钟 200MHz 周期 5ns
polar_clip 时钟 100MHz 周期 10ns (由 freqHz=100000000:polar_clip.ap_clk 设置)
理论最大吞吐 100 MSamples/s 受限于最慢的 polar_clip
跨时钟域 FIFO 深度 16 (典型) 吸收 200MHz→100MHz 的速率差

核心设计决策与权衡

1. 时钟频率选择: 200MHz vs 100MHz

决策: 将 DMA 引擎 (mm2s/s2mm) 配置为 200MHz,将信号处理内核 (polar_clip) 配置为 100MHz。

权衡分析:

方面 选择 200MHz/100MHz 的理由 替代方案 (全 200MHz) 替代方案 (全 100MHz)
功耗 polar_clip 运行在 100MHz,动态功耗降低 ~50% (P_dynamic ∝ f·V²) 功耗高 2x 与当前方案相同
性能 吞吐受限于 polar_clip (100MHz),但 DMA 可以突发填充 FIFO,利用率 100% DMA 更快,但 polar_clip 仍瓶颈,效率低 (50% 空闲) DMA 与处理速度匹配,无背压
资源 100MHz 的时序约束更松,可使用更小的 DSP/ LUT 实现 需要更激进的流水线,资源可能增加 10-20% 与当前方案相同
教学价值 展示跨时钟域配置的实际需求 过于简单,不展示 CDC 概念 无法展示高速 DMA 的优势

关键洞察: 这是一个异构频率设计,体现了 Versal 平台的核心优势——允许每个组件以其最佳效率点运行,而不是被迫适应全局时钟。

2. HLS vs RTL 实现选择

决策: 使用 Vitis HLS (C++) 实现 polar_clip,而非手写 RTL (Verilog/VHDL)。

权衡分析:

维度 HLS (C++) RTL (Verilog)
开发效率 高: 算法工程师可直接用 C 实现,修改-编译-仿真周期 < 5 分钟 低: 需要硬件工程师,开发周期数周
性能上限 中-高: HLS 工具自动流水线,但可能不如手工优化的 RTL (差距 10-30%) 极高: 可针对特定 FPGA 架构极致优化
可移植性 高: C 代码可在 x86 仿真,也可综合到不同 FPGA 系列 低: Verilog 通常绑定特定厂商/器件
调试可见性 高: 可使用 GDB/printf 调试 C 仿真,波形查看器查看 RTL 信号 中: 需要 RTL 仿真器和波形查看器
资源利用率 中: HLS 可能生成冗余逻辑,比手工 RTL 多 20-50% LUT/FF 优: 精确控制每个寄存器

设计意图: 这是一个教程示例,优先展示生产力快速迭代能力,而非极致性能。对于教学场景,学生修改 C++ 算法并立即看到硬件结果,比学习 Verilog 语法更有价值。此外,AMD 的 HLS 工具链针对 Versal 平台有深度优化,生成的 RTL 质量已接近手工编码。

3. AXI Stream vs AXI Full 接口选择

决策: 内核间使用 AXI4-Stream (axis),DDR 访问使用 AXI4-Full (m_axi)。

权衡分析:

特性 AXI4-Stream (axis) AXI4-Full (m_axi)
寻址 无地址,连续流 有地址,随机/突发访问
协议开销 极低: 仅数据 + TLAST/TKEEP 高: 地址通道 + 读/写响应通道
适合场景 流式信号处理 (每时钟一个样本) 大数据块传输 (帧/图像/矩阵)
背压处理 原生支持 (TREADY/TVALID) 需额外流量控制机制
延迟 低: 直接传输 高: 地址解码 + 内存访问

设计意图: 这是一个流式信号处理管道的设计。mm2ss2mm 负责将 DDR 中的大数据块转换为连续流(或反之),而 polar_clip 需要每时钟处理一个样本。使用 AXI Stream 消除了地址生成的开销,允许内核专注于计算。这也是 Vitis HLS 的默认和推荐模式用于 DSP 应用。


跨模块依赖与集成

上游依赖 (输入)

模块 关系 说明
versal_integration_baseline_data_movers 基线参考 本模块的 mm2s/s2mm 内核基于该基线模块的 DMA 设计,但增加了多时钟配置
rtl_ip_with_aie_system_instances 集成模式 本模块的 AIE 连接模式继承自该 RTL IP 集成模块

下游依赖 (输出)

模块 关系 说明
debug_emulation_and_performance_analysis 调试目标 本模块生成的波形和性能数据由该调试模块分析
post_link_recompile_and_external_traffic_generator 扩展模式 本模块的 polar_clip 内核被该外部流量生成器模块复用

横向依赖 (同级交互)

模块 交互方式 说明
versal_integration_baseline_data_movers 配置继承 共享相同的 mm2s/s2mm HLS 源码,但本模块修改了时钟约束
packet_switching_and_streaming 协议差异 本模块使用 AXI Stream,而该模块使用基于包的路由,两者是互斥的设计模式

子模块导航

本模块由三个协同工作的子模块组成,每个负责不同的系统层面:

1. pl_data_mover_kernels - PL 数据搬运器内核

负责数据 I/O 的子模块,包含 mm2s (Memory-to-Stream) 和 s2mm (Stream-to-Memory) 两个 HLS 内核。它们是系统的"大门",负责将 DDR 内存中的数据块转换为连续的 AXI 流,或将流数据写回内存。关键特性: 运行在 200MHz 时钟域,使用 HLS ap_ctrl_chain 接口实现流水线启动。

2. pl_polar_clip_processing_kernel - PL 极坐标限幅处理内核

负责信号处理的子模块,包含 polar_clip HLS 内核。这是系统的"心脏",实现了基于 CORDIC 算法的极坐标限幅 (CFR) 功能,用于降低通信信号的峰均比 (PAPR)。关键特性: 运行在 100MHz 时钟域(仅为 DMA 引擎速度的一半),使用纯组合逻辑和查找表实现低延迟 CORDIC 迭代。

3. system_level_kernel_instances_and_linkage - 系统级内核实例化与连接

负责系统集成的子模块,包含 system.cfg 配置文件。它是系统的"神经系统",定义了内核实例数量、时钟频率约束、以及 AXI 流端口的连接关系。关键特性: 使用 Vitis 连接性语法 (nk= 用于实例化,sc= 用于连接,freqHz= 用于时钟),实现了 200MHz 域与 100MHz 域的跨时钟域自动插入 FIFO。


新贡献者必知的陷阱与注意事项

1. 时钟频率配置的双重性 (The Dual Nature of Clock Config)

陷阱: 时钟频率可以在两个地方配置,且后者覆盖前者

  • HLS 配置阶段 (polar_clip.cfg): freqhz=200MHz 设置 HLS 综合的目标频率,影响工具对流水线 II (Initiation Interval) 的优化。
  • 系统集成阶段 (system.cfg): freqHz=100000000:polar_clip.ap_clk 设置实际实现的物理时钟频率。

后果: 如果在 polar_clip.cfg 中设置 200MHz,但在 system.cfg 中设置 100MHz,HLS 会按 200MHz 优化(可能使用更多流水线级数),但实际运行在 100MHz,造成资源浪费。反之,如果在 HLS 中按 100MHz 优化,但在系统中强制 200MHz,可能导致时序违例。

最佳实践: 保持两者一致,或在 HLS 阶段设置略高于系统需求的频率(如 HLS 250MHz,系统 200MHz),以留出时序裕量。

2. 跨时钟域 FIFO 深度的隐形约束

陷阱: 200MHz 到 100MHz 的速率差意味着上游每产生 2 个样本,下游才消费 1 个。如果 FIFO 深度不足,将导致溢出。

计算方法:

  • 假设 mm2s 以突发模式发送 1024 个样本(无背压间隔)
  • polar_clip 每 10ns 消费一个样本(100MHz)
  • mm2s 每 5ns 产生一个样本(200MHz)
  • 在 1024×5ns = 5.12μs 的突发期间,polar_clip 消费 512 个样本
  • 净积累: 1024 - 512 = 512 个样本在 FIFO 中

后果: 如果 FIFO 深度 < 512,将发生溢出,数据丢失。

Vitis 的自动处理: 在 system.cfg 中连接 sc= 时,Vitis 会自动插入 axis_aclkaxis_aresetn,并在工具链检测到跨时钟域时自动实例化异步 FIFO。但默认深度可能不足

最佳实践: 在 HLS 中使用 #pragma HLS stream variable=<stream_name> depth=1024 显式设置流深度,确保有足够的缓冲来吸收突发流量。

3. CORDIC 算法的定点精度陷阱

陷阱: polar_clip 使用定点数 (ap_int<16>, ap_int<32>) 而非浮点,存在精度损失和溢出风险。

关键代码分析:

typedef complex_types<ap_int<16> > ap_cint16;  // 16位实部 + 16位虚部
ap_int32 value_real_sq = value_real * value_real;  // 16bit × 16bit = 32bit

潜在问题:

  1. 乘法溢出: value_real 最大 32767,平方后为 1,073,676,289 (0x3FFF0001),刚好在 32 位有符号数范围内 (2^31-1 = 2,147,483,647)。但如果输入是 -32768 (0x8000),平方后为 1,073,741,824 (0x40000000),仍在范围内。边界情况安全

  2. CORDIC 增益: CORDIC 算法本身有增益 (~1.647),cos_sin_mag 函数中的 P_SCALE = 512C_SCALE = 1 用于补偿。如果缩放不当,中间结果可能溢出。

  3. 阈值比较: CFR_THRESHOLD = 11626,比较时计算 CFR_THRESHOLD*CFR_THRESHOLD = 135,163,876,在 32 位范围内。

验证策略: 测试用例应包括最大幅值输入 (32767+32767i) 和零输入,验证无溢出且限幅逻辑正确。

4. 系统配置文件中连接语法的微妙之处

陷阱: system.cfg 中的 sc= (stream connect) 语法有严格的命名规则和隐含假设。

示例分析:

sc=mm2s.s:ai_engine_0.DataIn1
sc=ai_engine_0.clip_in:polar_clip.in_sample
sc=polar_clip.out_sample:ai_engine_0.clip_out
sc=ai_engine_0.DataOut1:s2mm.s

微妙之处:

  1. 端口命名: mm2s.s 表示 mm2s 内核的 s (stream) 端口。这需要与 HLS 代码中的 hls::stream<> 变量名匹配。
  2. AIE 端口命名: ai_engine_0.DataIn1 是预定义的 AIE 接口名。命名约定 DataIn{0-3}DataOut{0-3} 是平台特定的。
  3. 隐式协议: sc= 假设 AXI4-Stream 协议,包括 TVALID, TREADY, TDATA, TLAST。如果 HLS 代码使用 ap_ctrl_none 但端口不是 axis,连接会失败。

常见错误:

  • 忘记 nk= (num kernels) 声明就使用 sc=,导致工具不知道内核存在
  • 端口名大小写不匹配 (HLS 中是 out_sample,cfg 中写成 out_sample 是对的,但 Out_sample 就错)
  • 时钟域指定错误: freqHz=100000000:polar_clip.ap_clk 如果写成 polar_clip.aclk 或漏掉 .ap_clk,时钟约束不生效

调试技巧: 构建失败时检查 _x/ 目录下的 *.xo 文件和 *.xclbin 构建日志,查找 CRITICAL WARNING 关于连接不匹配的信息。


总结: 给新贡献者的行动指南

如果你需要修改算法...

  1. 编辑 polar_clip.cpp: 重点修改 polar_clip 函数和 cos_sin_mag CORDIC 实现
  2. 注意定点数范围: 任何乘法操作 (*) 都要检查结果是否在 ap_int<32> 范围内
  3. C 仿真: 使用 g++ -I. polar_clip.cpp -o test 进行算法验证,确认修改逻辑正确
  4. HLS 综合: 运行 vitis_hls polar_clip.cfg,检查报告的 II (Initiation Interval) 和 Latency

如果你需要调整时钟...

  1. 修改 polar_clip.cfg: 调整 freqhz=200MHz 以改变 HLS 优化目标
  2. 修改 system.cfg: 调整 freqHz=100000000:polar_clip.ap_clk 以改变实际运行频率
  3. 保持同步: 确保 HLS 目标频率 ≥ 系统实际频率,通常 HLS 目标 = 系统频率 × 1.2 (20% 裕量)
  4. 跨时钟域检查: 如果改变 mm2s (200MHz) 或 polar_clip (100MHz) 的频率比,重新计算 FIFO 深度需求

如果你需要调试硬件...

  1. 仿真波形: 使用 Vitis Emulation 生成波形,关注 ap_start, ap_done, TVALID, TREADY 信号
  2. 检查 CDC: 如果在 200MHz→100MHz 边界看到数据丢失,检查 FIFO 的 fullempty 信号时序
  3. 内存对齐: 确保 DDR 缓冲区地址 4KB 对齐,使用 xrt::bo 的 flags 参数设置 XCL_BO_FLAGS_NONE
  4. 协议检查: 使用 ILA (Integrated Logic Analyzer) 插入到 mm2s.spolar_clip.in_sample 端口,捕获实时 AXI Stream 事务

子模块文档速查

根据你的关注点,直接跳转到对应的子模块文档:

如果你的问题是... 查看子模块
"如何修改 HLS 源码?" / "Vitis HLS 优化指令怎么用?" pl_data_mover_kernels (MM2S/S2MM 内核)
"CORDIC 算法如何实现?" / "CFR 阈值怎么调?" pl_polar_clip_processing_kernel (极坐标限幅内核)
"时钟频率在哪里配?" / "怎么连到 AI Engine?" system_level_kernel_instances_and_linkage (系统集成与连接)

常见错误速查表

症状 可能原因 解决方案
v++ 链接失败,报错连接不匹配 system.cfg 中的 sc= 端口名与 HLS 代码不匹配 检查 HLS 代码中的 hls::stream<> 变量名和 #pragma HLS INTERFACE 指定的端口名
硬件运行输出全零 polar_clip 时钟未启动或复位未释放 检查 system.cfg 中的 freqHz 是否正确应用,检查 xrt::run 是否正确启动所有内核
性能远低于预期 (如 10MS/s 而非 100MS/s) FIFO 深度不足导致频繁背压 在 HLS 中增加 #pragma HLS stream depth=2048,重新计算 FIFO 大小
输出数据有间断 (glitch) 跨时钟域 FIFO 的格雷码同步失败 确保 200MHz 和 100MHz 时钟来自同一个 MMCM/PLL 且相位对齐,或检查亚稳态处理

参考与延伸阅读

  • Vitis HLS 用户指南: 深入了解 HLS 优化指令 (UG1399)
  • Versal ACAP AI Engine 编程环境: AIE 与 PL 集成详情 (UG1076)
  • AXI 协议规范: 理解 AXI4-Stream 和 AXI4-Full 协议时序 (ARM IHI 0051A)
  • CORDIC 算法原理: 理解 cos_sin_mag 中的旋转模式和向量模式 (IEEE paper by Volder, 1959)
On this page