FPGA面试百问:从基础到实战全解析

下面给出"纯 FPGA 芯片"方向的 100 道中文面试题,问题顺序与原来 STM32 100 题一一对应,方便快速检索。题目涵盖 FPGA 基础、Verilog/VHDL、时钟、IO、资源、时序、高速收发、调试、实战项目等,既照顾初学者,也保留深入追问空间。

  1. FPGA 是什么?它基于什么硬件架构?

  2. Xilinx 7 系列、UltraScale+、Intel Agilex 的内核架构差异有哪些?

  3. 什么是 Xilinx 原语(primitive)?它的作用是什么?

  4. 描述 FPGA 从上电到用户逻辑开始运行的完整过程(POR→配置→DONE)。

  5. 什么是 JTAG ISP 与 Slave-Serial ISP?它们有何不同?

  6. FPGA 供电引脚(VCCINT、VCCAUX、VCCO、VTT、VREF)分别有什么作用?

  7. 什么是时钟树?为什么它在 FPGA 中很重要?

  8. 列举 FPGA 常见时钟源(外部晶振、MMCM、PLL、BUFG、GT 时钟)。

  9. 如何配置 MMCM 得到最高 600 MHz 时钟?给出计算步骤。

  10. 什么是 IOB?FPGA 的 IO 有几种工作模式?

  11. 推挽输出与开漏输出在 FPGA 里如何描述(OBUF vs OBUFT)?

  12. 如何把 FPGA 引脚配置为内部上拉输入?约束语法怎么写?

  13. 什么是引脚复用?如何把 IOB 设为 LVDS_25 差分对?

  14. 什么是 GIC 在 FPGA-SoC 里的角色?纯 FPGA 怎么办?

  15. FPGA 内部中断优先级如何管理?(软核 MicroBlaze 向量表)

  16. 什么是外部中断引脚?如何同步到时钟域?

  17. Systick 在 FPGA 软核里怎么实现?(AXI-Timer)

  18. 看门狗在 FPGA 里怎么实现?独立与窗口区别?

  19. 如何把 FPGA 从 Power-Gated 状态唤醒?

  20. 什么是位带?FPGA 没有位带怎么办?

  21. UART 通信的基本原理?FPGA 如何实现 115200?

  22. 如何用 Verilog 写 115200 波特率发生器?给出公式。

  23. FPGA 如何用中断方式接收不定长 UART 数据?

  24. 什么是 AXI-DMA?它有什么好处?

  25. 如何配置 AXI-DMA 做 UART 环回?

  26. SPI 有几种模式?由什么信号决定?

  27. 如何用 Verilog 写 SPI Master 全双工?

  28. I²C 起始/停止条件如何在 FPGA 时序里描述?

  29. 如何用 Verilog 软模拟 I²C?

  30. I²C 从机地址如何组成?

  31. FPGA 实现 I²C 要注意什么?(开漏、三态、建立/保持)

  32. 对比 UART、SPI、I²C 在 FPGA 的资源占用。

  33. 通用定时器在 FPGA 里如何写?(AXI-Timer)

  34. 如何用计数器产生 1 kHz PWM?

  35. PWM 频率与占空比由哪些寄存器决定?

  36. 如何用 FPGA 捕获外部脉冲宽度?

  37. 什么是正交编码器接口?如何用 FPGA 实现?

  38. 高级定时器 vs 通用定时器------FPGA 里怎么定义"高级"?

  39. 如何用定时器触发 ADC IP 核?

  40. ADC 分辨率是什么意思?FPGA 外接 AD9226 是多少位?

  41. 什么是"并行 ADC"与"串行 ADC"通道?

  42. 如何实现多通道 ADC 扫描?

  43. ADC 采样时钟抖动如何影响 SNR?

  44. 如何校准 FPGA 外接 ADC 的增益/偏移?

  45. 高速 DAC(AD9708)在 FPGA 下的用途?

  46. FPGA 内部如何实现高速比较器?(LUT+寄存器)

  47. 什么是 RTC 在 FPGA 外接场景?如何闹钟中断?

  48. 如何把数据备份到 FPGA 外接 FRAM?

  49. 什么是 FPGA DNA?如何读取?

  50. FPGA 配置 Flash(SPI/QSPI)如何组织扇区?

  51. 如何在 Zynq 裸机下读写 QSPI Flash?

  52. 什么是"选项字节"在 FPGA 的对应?(写保护位)

  53. 如何在 FPGA 写一个 golden-image 双启动?

  54. 如何把 FPGA 逻辑搬到外部 DDR 运行?(partial reconfiguration)

  55. 什么是 MMU?软核 MicroBlaze 带 MMU 吗?

  56. 如何用 MPU 保护 MicroBlaze 内存段?

  57. 什么是 DSP48E2?哪些 FPGA 系列支持?

  58. 如何用 DSP48 写 256 点 FFT?

  59. 什么是硬 FPU?哪些 FPGA SoC 带硬核 A53+FPU?

  60. 使用 FPU 需要注意什么?(上下文保存)

  61. FPGA 外接以太网 MAC 与 PHY 区别?

  62. 如何配置 LWIP 在 FPGA 软核跑 TCP?

  63. USB 有哪几种传输类型?FPGA 如何实现?

  64. 如何把 FPGA 做成 USB HID?

  65. 如何把 FPGA 做成 USB CDC?

  66. CAN 控制器在 FPGA 软核对帧如何区分?

  67. 如何配置 CAN 过滤器?

  68. 如何计算 CAN 波特率?

  69. SDIO 与 SPI 模式读写 SD 卡速度差异?

  70. 如何通过 FMC 驱动 TFT 液晶屏?

  71. 什么是 FPGA 内部 TFT-LCDC IP?

  72. D-PHY/CSI-2 RX 子系统用于什么?

  73. 如何用 FPGA 驱动 WS2812B?(串行级联时序)

  74. 如何用 FPGA 读旋转编码器?(去抖+四倍频)

  75. 如何用 FPGA 驱动步进电机?(PWM+方向)

  76. 如何在 FPGA 实现 PID 控制器?(Verilog 定点)

  77. 如何在 FPGA 软核跑 FreeRTOS?

  78. FreeRTOS 任务状态有哪几种?

  79. 什么是信号量、互斥量、消息队列?

  80. 如何避免优先级反转?

  81. 什么是内存碎片?如何应对?

  82. 如何用 Vivado Block Design 自动生成连线?

  83. Xilinx IP 的"裸机驱动"与"Linux 驱动"区别?

  84. 轮询、中断、DMA 三种 IP 模式对比?

  85. 如何处理 AXI-DMA 超时错误?

  86. 如何自定义 IP 的中断回调?

  87. 如何通过 JTAG 调试 FPGA?

  88. ILA 断点有哪几种?

  89. 如何重定向 printf 到 UART?

  90. 如何使用 ILA 进行更高效调试?

  91. 如何测量 Verilog 代码执行时间?(ILA 时间戳)

  92. 如何配置 FPGA 进入低功耗?(时钟门控+Power-Gating)

  93. 低功耗下哪些资源可保持?

  94. 如何分析和优化 FPGA 功耗?(Vivado Power Report)

  95. PCB 上 FPGA 复位和晶振电路注意什么?

  96. 什么是去耦电容?为什么靠近引脚?

  97. 高速差分对如何与数字部分隔离?

  98. FPGA 配置失败常见原因?(DONE 不上拉、bitstream 损坏)

  99. 如何用看门狗提升 FPGA 系统可靠性?

  100. 如何在量产中实现 FPGA 远程在线升级?(Golden/Multiboot、ICAP、RSU)

------完------

以下是对您提出的100个Zynq嵌入式系统相关面试问题的完整、详细、专业级回答,由一位具有20年经验的嵌入式软硬件工程师兼计算机科学家撰写。内容涵盖Zynq架构、启动流程、外设驱动、电源管理、时钟系统、通信接口、安全机制、低功耗设计、PCB布局、调试方法等全栈知识。


1. Zynq 到底是什么?它"基于"什么硬件架构?

Zynq 是 Xilinx(现 AMD)推出的 SoC(System-on-Chip)平台 ,核心思想是将 可编程逻辑(PL, Programmable Logic)硬核处理器系统(PS, Processing System) 集成在同一芯片上。

  • 硬件架构基础
    • Zynq-7000 系列 :基于 ARM Cortex-A9 MPCore 双核处理器(32位 ARMv7-A 架构),搭配 Artix-7 或 Kintex-7 级别的 FPGA 逻辑。
    • UltraScale+ MPSoC 系列 (如 Zynq UltraScale+ MPSoC):采用 异构多核架构 ,包括:
      • 应用处理器单元(APU):双/四核 Cortex-A53(64位 ARMv8-A)
      • 实时处理器单元(RPU):双核 Cortex-R5F(带 FPU,用于实时控制)
      • 可选 Mali-400 GPU
      • PL 基于 UltraScale+ 架构(支持高速收发器、DSP48E2、Block RAM 等)

Zynq 的本质是 软硬协同 SoC ,通过 AXI 总线互连实现 PS 与 PL 的高速数据交换(最高可达数百 MB/s)。


2. Zynq-7000 与 UltraScale+ MPSoC 的"处理系统(PS)"内核区别有哪些?

特性 Zynq-7000 UltraScale+ MPSoC
主 CPU 双核 Cortex-A9 (32位) 四核 Cortex-A53 (64位) + 双核 Cortex-R5F
指令集 ARMv7-A ARMv8-A (A53), ARMv7-R (R5)
虚拟化 不支持 A53 支持虚拟化扩展
安全 TrustZone (A9) 更强:Secure Boot、CSU、PMC、加密引擎
内存管理 MMU (A9) A53: MMU, R5: MPU
浮点 A9 可选 VFPv3 A53: NEON + VFPv4, R5: 单精度 FPU
功耗管理 基础休眠 多域电源管理(PMC 控制)
启动方式 BootROM → FSBL CSU ROM → PMU Firmware → ATF → U-Boot
安全启动 SHA-256 + RSA-2048 SHA-3 + RSA-4096 / ECC

关键差异 :MPSoC 引入了 Platform Management Unit (PMU)Configuration Security Unit (CSU),支持更复杂的电源/安全策略。


3. 什么是 Xilinx 提供的"硬件抽象层"与"板级支持包"(BSP)?它们作用是什么?

  • 硬件抽象层(HAL)

    • 是 Xilinx SDK/PetaLinux 提供的一组 C 函数库,封装底层寄存器操作。
    • 例如:XUartPs_Send()XGpio_SetDataDirection()
    • 目标:屏蔽硬件细节,使应用代码可移植。
  • 板级支持包(BSP)

    • 包含 HAL + 链接脚本 (.ld)、启动代码 (crt0.S)、配置头文件(xparameters.h)。
    • 由 Vivado 自动生成,反映当前硬件设计(IP 地址、中断号、时钟频率等)。
    • 作用:为裸机或 RTOS 提供 运行环境初始化

注意:在 Linux 下,BSP 被 Device Tree 替代;在裸机/FreeRTOS 中,BSP 是必需的。


4. 描述 Zynq 从上电到开始执行 main() 的完整启动序列

Zynq-7000 启动流程
  1. 上电复位BootROM (固化在芯片内部)执行。
    • 检测启动模式(QSPI、SD、JTAG、NAND 等)
    • 加载 FSBL(First Stage Boot Loader) 到 OCM(On-Chip Memory)
  2. FSBL 执行
    • 初始化 DDR、MIO、时钟
    • 加载 PL 比特流(可选)
    • 加载 SSBL(Second Stage Boot Loader) ,通常是 U-Boot
  3. U-Boot 执行
    • 初始化外设、网络、存储
    • 加载 Linux 内核 + Device Tree + RootFS
  4. Linux 启动init → 用户空间 → main()(若为用户程序)
UltraScale+ MPSoC 启动流程更复杂
  • BootROM → PMU Firmware (运行在 PMU 上)→ ARM Trusted Firmware (ATF)U-Boot → Linux

关键点:FSBL 是 Xilinx 定义的第一阶段引导程序,必须由用户编写或使用 Xilinx 提供模板。


5. 什么是 FSBL?什么是 CSU ROM?二者差别在哪?

  • FSBL(First Stage Boot Loader)

    • 用户编写的 第一阶段引导程序(通常用 C 编写)
    • 运行在 OCM(256 KB SRAM)
    • 负责:DDR 初始化、PL 配置、加载 U-Boot
    • 由 Xilinx SDK 生成模板
  • CSU ROM(Configuration Security Unit ROM)

    • 仅存在于 UltraScale+ MPSoC
    • 安全启动根信任锚,固化在芯片中
    • 负责验证 PMU Firmware 的签名(SHA-3 + RSA/ECC)
    • 不可修改,比 Zynq-7000 的 BootROM 更安全

区别:FSBL 是软件,CSU ROM 是硬件固件;CSU ROM 在安全启动链中地位更高。


6. Zynq 供电引脚分别给谁供电?

电源引脚 供电对象 典型电压
VCCPINT PS 内核逻辑(CPU、Cache、总线) 1.0 V
VCCPAUX PS 辅助电路(PLL、I/O bank 控制器) 1.8 V
VCCO_MIO MIO Bank 0/1/2/3 的 I/O 电压 1.8/2.5/3.3 V(可配)
VCCO_0 ~ VCCO_3 对应 MIO Bank 的输出驱动电压 同上
VCCINT PL 内核逻辑(LUT、FF、BRAM) 0.95~1.0 V
VCCAUX PL 辅助(配置逻辑、IO buffer) 1.8 V
VCCBRAM Block RAM 专用 1.0 V

注意:MIO Bank 电压必须一致,不能跨 bank 混用不同电压。


7. 什么是 Zynq"时钟架构"?为什么 PS 与 PL 时钟树分开又耦合?

  • 时钟架构

    • PS 有 独立 PLL 系统(ARM PLL、DDR PLL、IO PLL)
    • PL 有 MMCM/PLL 原语(用户可配置)
    • 两者通过 FCLK_CLKx 信号连接(PS 输出时钟到 PL)
  • 为何分开又耦合?

    • 分开:PS 需要稳定、低抖动时钟(尤其 DDR、CPU);PL 时钟需灵活(用户自定义频率/相位)
    • 耦合:PS 需向 PL 提供参考时钟(如 100 MHz 给 AXI 接口);PL 也可反馈时钟给 PS(较少见)

设计原则:隔离噪声 + 提供同步接口。


8. Zynq-7000 PS 端主要时钟源

  • 外部晶振:通常 33.333 MHz(也可 50 MHz)
  • ARM PLL:倍频后供 Cortex-A9(最高 1 GHz)
  • DDR PLL:供 DDR 控制器(通常 533 MHz)
  • IO PLL:供外设(UART、SPI、USB 等)
  • 衍生时钟 :通过 Clock Generator 分频得到各外设时钟

9. 如何把 ARM PLL 配置到最高 1 GHz?需要修改哪些寄存器?

Zynq-7000 最高 CPU 频率 = 1 GHz(需满足工艺/温度条件)

步骤

  1. 确保输入时钟为 33.333 MHz

  2. 计算 PLL 参数:

    • Feedback divisor (FBDIV) = 60 → 33.333 × 60 = 2000 MHz (VCO)
    • Output divisor = 2 → 2000 / 2 = 1000 MHz
  3. 写寄存器(地址基于 SLCR 基址 0xF8000000):

    复制代码

    c

    编辑

    复制代码
    // Unlock SLCR
    Xil_Out32(0xF8000008, 0xDF0D);
    
    // Set ARM PLL CFG: FBDIV=60, DIV2=1
    Xil_Out32(0xF8000100, (60 << 12) | (1 << 9));
    
    // Bypass reset, enable PLL
    Xil_Out32(0xF8000100, reg | 0x01);
    
    // Wait for lock
    while (!(Xil_In32(0xF8000100) & 0x02));
    
    // Switch CPU clock to ARM PLL
    Xil_Out32(0xF8000120, 0x01); // ARM_CLK_CTRL

注意:超频需谨慎,确保散热和供电能力。


10. 什么是 MIO/EMIO?它们能配置成几种工作模式?

  • MIO(Multiplexed I/O)
    • PS 固定引出的 54 个引脚(Bank 0~3)
    • 可复用为 UART、SPI、I2C、GPIO 等
  • EMIO(Extended MIO)
    • 通过 PL 引出的 GPIO(最多 64+64=128 位)
    • 本质是 PS 的 GPIO 信号路由到 PL

工作模式(每 pin):

  1. 外设功能(如 UART1_TX)
  2. GPIO 输入/输出
  3. 高阻态(Tri-state)
  4. 内部上拉/下拉使能

配置寄存器MIO_PIN_x(SLCR 偏移 0x700 + x×4)


11. PS 端 MIO 与 PL 端普通 IO 在电气特性上有哪些区别?

特性 MIO (PS) PL IO
驱动能力 固定(4/8/12 mA) 可编程(2~24 mA)
电压标准 仅支持 LVCMOS18/25/33 支持 LVDS、SSTL、HSTL 等
上下拉 内部可配 需外部电阻或 IO 标准支持
速度 ≤ 50 MHz(一般外设) 可达 GHz(配合 GT transceiver)
ESD 保护 强(面向板级连接) 一般

结论:MIO 适合连接标准外设;PL IO 适合高速/差分/定制接口。


12. 如何把 MIO pin-10 配置为 UART1_RX 并启用内部上拉?

复制代码

c

编辑

复制代码
// MIO10 属于 Bank 1,需先设 VCCO_1 = 1.8V(硬件)
// 寄存器地址:SLCR_MIO_PIN_10 = 0xF8000728

Xil_Out32(0xF8000728,
    (1 << 13) |   // pull-up enable
    (0 << 12) |   // disable pull-down
    (4 << 7)  |   // disable tri-state
    (0 << 6)  |   // disable L0 disable
    (0 << 5)  |   // disable speed mode
    (0 << 4)  |   // disable IO type
    (0 << 1)  |   // disable disable rcvr
    (1)           // MIO10 = UART1_RX (peripheral function 1)
);

查表:Xilinx UG585 表 11-2 显示 MIO10 的 UART1_RX 功能编号为 1。


13. 什么是"引脚复用"?如何把 EMIO GPIO 引到 PL 端引脚?

  • 引脚复用:一个物理引脚可配置为多种功能(UART/SPI/GPIO 等),通过寄存器选择。
  • EMIO 到 PL 引脚
    1. 在 Vivado Block Design 中,将 PS IP 的 EMIO GPIO 引出为顶层端口
    2. 在约束文件(.xdc)中绑定该端口到具体 FPGA 引脚
    3. 在软件中通过 XGpio 驱动操作

示例:EMIO[0] → top_level_pin → PACKAGE_PIN AA12


14. 什么是 GIC?它在 Zynq 中断体系里扮演什么角色?

  • GIC(Generic Interrupt Controller)
    • ARM 定义的标准中断控制器(Cortex-A9/A53 均集成)
    • 在 Zynq 中位于 PS 内部
  • 作用
    • 接收 192 个中断源(外设 + PL→PS 中断)
    • 支持 优先级、屏蔽、分发(多核)
    • 将中断路由到 CPU 的 IRQ/FIQ

寄存器基址:0xF8F01000(Zynq-7000)


15. Zynq 中断号如何分组?如何给 IRQ #61 设置优先级 0xA0?

  • 中断分组(Zynq-7000):

    • 0--31:SGI(软件生成)
    • 32--63:PPI(私有外设,如 Timer、WDT)
    • 64--191:SPI(共享外设,如 UART、GPIO、PL 中断)
  • IRQ #61 属于 PPI(可能是 TTC0)

  • 设置优先级

    复制代码

    c

    编辑

    复制代码
    // GIC Distributor: Priority Register for INTID 61
    // Each reg holds 4 priorities (8-bit each)
    uint32_t reg_addr = 0xF8F01400 + (61 / 4) * 4;
    uint32_t shift = (61 % 4) * 8;
    uint32_t val = Xil_In32(reg_addr);
    val = (val & ~(0xFF << shift)) | (0xA0 << shift);
    Xil_Out32(reg_addr, val);

注意:优先级数值越小,优先级越高(0x00 最高)。


16. 什么是 PL→PS 中断(IRQ-F2P)?如何级联 16 根?

  • IRQ-F2P :PL 向 PS 发送的 Fabric-to-Processor 中断

    • 最多 16 根(IRQ_F2P[15:0])
    • 映射到 GIC SPI 中断号 61--76(Zynq-7000)
  • 级联方法

    1. 在 PL 中用 AXI Interrupt Controller IP
    2. 将多个 PL 中断源接入该 IP
    3. 该 IP 输出单根中断到 PS 的 IRQ_F2P[0]
    4. 在软件中读取 IP 的状态寄存器判断具体源

优势:节省 PS 中断线资源。


17. Generic Timer 与 SCU Timer 区别?各自用途?

特性 Generic Timer SCU Timer
位置 每个 A9 核私有 SCU(Snoop Control Unit)共享
位宽 64-bit 32-bit
用途 高精度计时、调度 系统级定时(如 OS tick)
中断 私有 PPI 共享 SPI

实际使用:Linux 用 Generic Timer 做 sched_clock;裸机常用 SCU Timer 做 delay。


18. Zynq 看门狗(SWDT)与 AWDT 有什么区别?如何防止"二次喂狗"攻击?

  • SWDT(System Watchdog Timer)

    • 由 PS 控制,可被软件禁用
  • AWDT(Always-on Watchdog Timer)

    • 位于 RTC 域,即使深睡也运行
    • 无法被软件完全关闭(除非断电)
  • 防"二次喂狗"攻击

    • 使用 窗口看门狗模式:只能在特定时间窗口内喂狗
    • 结合 安全启动 + 加密校验,防止恶意代码篡改喂狗逻辑
    • 在 SIL2/3 系统中,双看门狗(SWDT + AWDT) 互相监控

19. 如何把 Zynq 从"深睡"(Deep-Sleep) 唤醒?唤醒源有哪些?

  • 深睡模式:关闭 PS 主电源(VCCPINT),仅保留 RTC、AWDT、部分 GPIO
  • 唤醒源
    • RTC Alarm
    • AWDT 超时
    • MIO GPIO(配置为唤醒引脚)
    • USB 唤醒(若支持)
  • 唤醒流程
    • BootROM 重新执行 → 加载 FSBL → 恢复上下文(需软件保存)

注意:PL 配置丢失,需重新下载比特流。


20. 什么是 Zynq 的"寄存器位带"(bit-banding)?为什么 PL 端没有?

  • Bit-banding
    • ARM Cortex-M 特性,允许 原子地操作单个 bit
    • 通过映射 1 MB 位带区到 32 MB 别名区
  • Zynq(A9/A53)不支持 bit-banding
    • 因为它是 Application Profile,非 Microcontroller Profile
    • PL 更无此概念(FPGA 逻辑直接操作信号)

替代方案 :使用 LDREX/STREX 实现原子操作。


21. UART 控制器 16550 兼容模式指什么?波特率误差允许多大?

  • 16550 兼容:寄存器布局、FIFO 结构、中断机制与 NS16550 兼容
  • 波特率误差
    • ≤ ±3% 可靠通信
    • 超过 5% 可能导致帧错误

22. 如何配置 UART1 波特率 115200,参考时钟 50 MHz?

公式:

CD=16×BaudRateRefClk​=16×11520050,000,000​≈27.1267

取整 CD = 27,计算实际波特率:

Actual=16×2750e6​≈115740.7→误差=+0.47%

寄存器设置

复制代码

c

编辑

复制代码
// UART1 base = 0xE0001000
Xil_Out32(0xE0001000 + 0x00, 0x80); // DLAB=1
Xil_Out32(0xE0001000 + 0x00, 27);   // DLL
Xil_Out32(0xE0001000 + 0x04, 0);    // DLM
Xil_Out32(0xE0001000 + 0x00, 0x03); // 8N1, DLAB=0

23. PL 端 AXI-UART-lite 如何通过中断接收"不定长"数据包?

  • 问题 :AXI UART Lite 无 FIFO 满中断,只有 接收数据就绪中断
  • 解决方案
    1. 开启中断
    2. 中断服务程序读取字符
    3. 使用 超时机制 判断包结束(如 10ms 无新数据)
    4. 或约定 包尾标志(如 '\n')

注意:不适合高速流式数据,建议用 AXI UART 16550 或 DMA。


24. Central DMA、DMA-330、AXI-DMA?各适合什么场景?

类型 描述 适用场景
Central DMA PS 内置 DMA,用于 MIO 外设(如 SD、UART) 低速外设数据搬移
DMA-330 ARM PL330,高性能,支持 scatter-gather Linux 内核驱动(如 GEM)
AXI-DMA PL IP,专为 PL↔PS 高速传输设计 视频流、雷达数据、高速 ADC/DAC

性能:AXI-DMA > DMA-330 > Central DMA


25. 如何配置 AXI-DMA 在 MM2S 通道做 UART 自发自收?

不可行 !AXI-DMA 用于 内存 ↔ PL,不能直接连 UART。

正确做法

  • 用 AXI-DMA 将数据从 DDR 发送到 PL 的 FIFO
  • PL 逻辑从 FIFO 读取并驱动 UART TX
  • UART RX 接回 PL,写入另一 FIFO,再由 AXI-DMA 读回 DDR

本质:需 PL 逻辑桥接。


26. SPI 控制器支持哪几种"时钟相位/极性"?寄存器在哪一位?

  • 四种模式

    • Mode 0: CPOL=0, CPHA=0
    • Mode 1: CPOL=0, CPHA=1
    • Mode 2: CPOL=1, CPHA=0
    • Mode 3: CPOL=1, CPHA=1
  • 寄存器SPI Configuration Reg (0x00)

    • Bit 0: CPOL
    • Bit 1: CPHA

27. 如何使 SPI0 做 Master、全双工、SCLK=20 MHz?

假设 IO_PLL = 100 MHz:

Divisor=2×20100​=2.5→取整 3→实际 SCLK=16.67MHz

寄存器设置

复制代码

c

编辑

复制代码
// Enable master, full-duplex
Xil_Out32(SPI0_BASE + 0x00, 0x186); // Master, no CS, 8-bit
Xil_Out32(SPI0_BASE + 0x04, 0x03);  // Baud rate divisor = 3
Xil_Out32(SPI0_BASE + 0x00, 0x186 | 0x02); // Enable

注意:Zynq SPI 最高约 50 MHz(受限于 IO 速度)。


28. I²C 控制器如何产生"重复起始位"?寄存器流程?

  1. 发送地址 + Write
  2. 写寄存器地址
  3. 不发送 STOP
  4. 发送 Repeated Start (通过设置 CONTROL.REP_START = 1
  5. 发送地址 + Read
  6. 读数据,最后发 STOP

关键寄存器

  • I2C_CONTROL:Bit 5 = REP_START
  • I2C_DATA:写地址/数据
  • I2C_INTERRUPT_STATUS:等待传输完成

29. 如何用 PL 端普通 IO"软模拟"I²C?给出 Verilog 状态机框架。

复制代码

verilog

编辑

复制代码
typedef enum {
    IDLE, START, ADDR_WR, DATA_WR, REP_START, ADDR_RD, DATA_RD, STOP
} i2c_state_t;

always @(posedge clk) begin
    case (state)
        IDLE: if (start_cmd) state <= START;
        START: begin
            sda <= 1; scl <= 1;
            #5 sda <= 0; // hold low
            state <= ADDR_WR;
        end
        ADDR_WR: begin
            // shift out 7-bit addr + 0
            if (bit_count == 8) state <= DATA_WR;
        end
        // ... similar for others
        STOP: begin
            sda <= 0; scl <= 1;
            #5 sda <= 1;
            state <= IDLE;
        end
    endcase
end

关键:严格遵循 I²C 时序(tHD;STA, tSU;STO 等)。


30. I²C 从机 7 位地址与 10 位地址在 Zynq 寄存器里如何区分?

  • 7-bit 地址 :直接写入 I2C_ADDRESS 寄存器(bit 6:0)
  • 10-bit 地址
    • 首字节 = 1111 0xx0(xx = 高2位)
    • 次字节 = 低8位
    • Zynq 控制器自动处理,无需特殊寄存器设置
    • 但需确保从机支持 10-bit

注意:Zynq I²C 控制器默认支持 10-bit 寻址。


31. Zynq I²C 外设常遇到的"时钟拉伸"问题如何排查?

  • 现象:SCL 被从机拉低,主机卡死
  • 排查步骤
    1. 用示波器确认 SCL 是否被拉低
    2. 检查从机是否忙(如 EEPROM 正在写)
    3. 在软件中增加 超时检测(轮询 SCL 状态)
    4. 若使用中断,确保及时响应
    5. 考虑降低时钟频率(减小从机压力)

设计建议:避免在中断中做 I²C,改用任务级。


32. 对比 UART、SPI、I²C 在 Zynq 中的资源占用与带宽

接口 带宽 引脚数 CPU 占用 PL 资源
UART ≤ 10 Mbps 2 高(无 DMA)
SPI ≤ 50 Mbps 3--4 中(可用 DMA)
I²C ≤ 400 kHz (Fast) 2 高(bit-bang 风险)

结论:高速用 SPI,简单传感器用 I²C,调试用 UART。


33. PS 端 TTC(Triple-Timer Counter)有哪些工作模式?

  • Interval Mode:定时中断
  • PWM Mode:输出方波
  • Capture Mode:捕获外部事件时间戳
  • Event Counter Mode:计数外部脉冲

34. 如何用 TTC 产生 1 kHz PWM?寄存器步骤?

假设 CPU_1x = 133 MHz:

Period=1000133e6​=133000 ticks

步骤

  1. 设置 CLK_CNTRL = 0x01(CPU_1x)
  2. CNT_CNTRL = 0x21(Waveform Mode + Match Enabled)
  3. INTERVAL_VAL = 133000 - 1
  4. MATCH[0] = 66500(50% 占空比)
  5. IER = 0x01(使能中断,可选)

35. PWM 占空比由 TTC 的哪个寄存器决定?

  • MATCH[0] 寄存器:决定高电平持续时间
  • 占空比 = MATCH[0] / INTERVAL_VAL

36. 如何用 TTC 捕获外部正脉冲宽度?精度如何计算?

  • 配置为 Capture Mode
  • 上升沿触发 capture1,下降沿触发 capture2
  • 脉宽 = capture2 - capture1
  • 精度 = 1 / CPU_1x 频率(如 133 MHz → 7.5 ns)

37. PL 端 AXI-Timer 的"产生/捕获"模式?

  • Generate Mode:输出 PWM
  • Capture Mode:记录输入信号边沿时间
  • 通过 TCSR 寄存器配置

38. PL 端"高速"AXI-Timer 与 PS 端 TTC 在性能上差多少?

  • TTC:最大时钟 = CPU_1x(~133 MHz)→ 精度 ~7.5 ns
  • AXI Timer:可接 PL 时钟(如 200 MHz)→ 精度 ~5 ns
  • 差异不大,但 AXI Timer 可定制更高频率

39. 如何用 AXI-PWM-IP 触发 PL 端 ADC IP 核?

  • 将 AXI-PWM 的输出连接到 ADC 的 采样使能(sample_en) 信号
  • PWM 高电平时启动 ADC 转换
  • 可实现 同步采样

40. XADC 与 ADC 的"分辨率"分别是多少位?采样率多高?

  • XADC (Zynq 内置):
    • 分辨率:12 位
    • 采样率:1 MSPS(单通道)
  • 外部 ADC (如 via SPI):
    • 可达 16--24 位,10+ MSPS

41. 什么是 XADC 的"同步采样"模式?

  • 使用 SYNC 引脚 外部触发
  • 多个 XADC(或多通道)同时采样
  • 用于三相电力测量等场景

42. 如何实现 16 通道 XADC 自动扫描?

  1. 配置 SEQ Register 使能通道 0--15
  2. 设置 SEQ Mode = Continuous
  3. 读取 FIFO 获取结果(自动排序)

43. XADC 采样时间与输入阻抗如何折衷?

  • 高输入阻抗 → 采样电容充电慢 → 需更长 Acquisition Time
  • XADC 允许配置 Channel AveragingSampling Rate
  • 建议:源阻抗 < 1 kΩ,否则加缓冲运放

44. 如何对 XADC 做"增益误差"校准?

  • 使用 Internal Calibration

    复制代码

    c

    编辑

    复制代码
    XSysMon_SetSequencerMode(&SysMonInst, XSM_SEQ_MODE_SAFE);
    XSysMon_SelfCalibrate(&SysMonInst);
  • 或使用 外部精密电压源 进行两点校准(offset + gain)


45. 高速 DAC (AXI-DDS/AXI-DAC) 在 PL 端典型用途?

  • 任意波形发生器
  • 通信调制(QPSK、OFDM)
  • 雷达 chirp 信号生成

46. 什么是 PL 端"高速比较器"原语?给出 LVDS 比较例子。

  • 原语IBUFDS + LUTCFGLUT5

  • LVDS 比较

    复制代码

    verilog

    编辑

    复制代码
    IBUFDS #(.DIFF_TERM("TRUE")) ibufds_inst (
        .I(vp), .IB(vn), .O(cmp_out)
    );

    直接输出数字比较结果。


47. 什么是 RTCA (Real-Time Clock Alarm)?如何产生中断唤醒?

  • RTCA 是 RTC 的 闹钟功能
  • 设置 RTC_ALARM 寄存器为目标时间
  • 到时产生中断 → 可配置为唤醒源

48. 如何借助 RTC 的"电池备份域"保存 64 字节数据?

  • 访问 Battery-backed SRAM(地址 0xF8005000)
  • 即使主电源关闭,只要 VBAT 存在,数据不丢失
  • 用于保存设备状态、校准参数等

49. Zynq 的"DNA"与"PS Serial Number"各多少位?怎么用?

  • Device DNA57 位,唯一芯片 ID,通过 JTAG 读取
  • PS Serial Number64 位,存储在 EFUSE 中,软件可读
  • 用途:软件授权、设备追踪、安全认证

50. Zynq 启动镜像 BOOT.BIN 由哪些"分区"组成?

  • Boot Header(固定格式)
  • FSBL.elf
  • system.bit(PL 比特流,可选)
  • u-boot.elf(或 application.elf)
  • Partition Header Table(描述各分区属性)

bootgen 工具生成。


51. 如何在 Linux 下读写 QSPI Flash 的 raw 页?

复制代码

bash

编辑

复制代码
# 使用 mtd 设备
flash_erase /dev/mtd0 0x0 0x100000
nandwrite /dev/mtd0 firmware.bin
hexdump /dev/mtd0

需在设备树中启用 cfi-flashspi-nor 驱动。


52. 什么是"启动头"(Boot Header)?如何修改启动频率?

  • Boot Header:BOOT.BIN 前 0x8C0 字节,含镜像信息
  • 修改启动频率
    • 在 FSBL 中调用 set_pll()
    • 或在 Vivado 中设置 PS IP 的时钟频率 → 自动生成正确头

53. 如何写一段"裸机"FSBL 实现 PL 比特流先下载后跳转?

复制代码

c

编辑

复制代码
int main() {
    init_uart();
    init_ddr();
    load_bitstream("system.bit"); // via SD/QSPI
    Xil_DCacheFlush();
    Xil_ICacheInvalidate();
    void (*app)() = (void*)APP_ADDR;
    app();
}

使用 Xilinx FSBL 模板 + 自定义加载逻辑。


54. 如何把 U-Boot relocate 到 DDR 高端地址运行?

  • 修改 CONFIG_SYS_TEXT_BASE in include/configs/zynq-common.h
  • 例如:#define CONFIG_SYS_TEXT_BASE 0x30000000
  • U-Boot 会自动 copy 自身到该地址并跳转

55. 什么是 MMU?A53 与 R5 的 MMU/MPU 差异?

  • MMU:内存管理单元,支持虚拟地址 → 物理地址映射(Linux 必需)
  • A53:完整 MMU(支持 4KB/2MB/1GB 页)
  • R5 :只有 MPU(Memory Protection Unit),支持区域保护,无地址转换

56. 如何配置 A53 的 TTBR0/TTBR1 实现 DDR 1 GB 映射?

  • 使用 1GB block descriptor(Level 1 页表)
  • TTBR0 指向页表基址
  • 页表项:VA[38:30] → PA[38:30] | 0x40001(1GB block, inner shareable)

57. 什么是 NEON?哪些 Zynq 系列支持?

  • NEON:ARM SIMD 指令集,加速 DSP/图像处理
  • Zynq-7000 :Cortex-A9 不支持
  • UltraScale+ MPSoC :Cortex-A53 支持 NEON

58. 如何用 NEON 写 128 点 FFT 蝶形运算?

使用 vld1, vmul, vadd, vsub 等指令处理复数对。

复制代码

c

编辑

复制代码
float32x4_t a = vld1q_f32(&x[i]);
float32x4_t b = vld1q_f32(&x[i+4]);
float32x4_t w = vld1q_f32(&twiddle[k]);
float32x4_t wb = vmulq_f32(b, w);
float32x4_t sum = vaddq_f32(a, wb);
float32x4_t diff = vsubq_f32(a, wb);

59. R5 的"单精度 FPU"与 A53 的"双精度 FPU"?

  • R5F :支持 single-precision (32-bit) IEEE754
  • A53 :支持 double-precision (64-bit) + NEON

60. 使用 FPU 中断现场保存要注意哪些寄存器?

  • A53 :需保存 V0-V31, FPSR, FPCR
  • R5S0-S31, FPSCR
  • 在中断入口用 vpush / fstmia 保存

61. GEM 与 PHY 在 RGMII 接口上如何约束时序?

  • 使用 IDELAY 调整 RX/TX 时序

  • 约束文件中指定:

    复制代码

    tcl

    编辑

    复制代码
    set_input_delay -clock rgmii_rx_clk -max 2.0 [get_ports rgmii_rxd*]
    set_output_delay -clock rgmii_tx_clk -max 2.0 [get_ports rgmii_txd*]

62. 如何配置 PetaLinux 下的 LWIP 实现 1000 M TCP 回环?

  • project-spec/meta-user/recipes-apps/ 添加 lwip app
  • 使用 netif_loopback() 或直接 tcp_connect() 到 127.0.0.1
  • 确保设备树启用 GEM

63. USB 2.0 OTG 控制器支持哪四种传输类型?

  • Control Transfer
  • Bulk Transfer
  • Interrupt Transfer
  • Isochronous Transfer

64. 如何将 Zynq 配置为 USB HID 鼠标?

  • 在 Linux 中加载 g_hid gadget 驱动
  • 或裸机使用 Xilinx USB driver + HID descriptor

65. 如何将 Zynq 配置为 USB CDC-ACM 虚拟串口?

复制代码

bash

编辑

复制代码
modprobe g_serial
echo "CDC ACM" > /sys/kernel/config/usb_gadget/g1/functions/acm.usb0

66. CAN 控制器如何区分标准帧、扩展帧、远程帧?

  • 标准帧:IDE=0
  • 扩展帧:IDE=1
  • 远程帧:RTR=1

寄存器 CAN_ID 中包含这些位。


67. 如何给 CAN 控制器加"接受过滤掩码"?

配置 AFMR(Acceptance Filter Mask Register)和 AFIR(ID Register)


68. 如何计算 CAN 波特率 1 Mbps,参考时钟 40 MHz?

  • Prescaler = 4
  • TS1 = 7, TS2 = 2 → TQ = 10
  • Bit rate = 40e6 / (4 × 10) = 1 Mbps

69. SDIO 与 SPI 模式读写 eMMC 速度差多少?

  • SDIO:4-bit mode → ~104 Mbps
  • SPI:≤ 20 Mbps
  • 差 5 倍以上

70. 如何通过 FMC/HP 端口驱动 8080 并口 TFT?

  • 用 PL 实现 8080 时序 FSM
  • 数据总线接 HPx_Dxx,控制信号(RS, WR, RD)接 GPIO
  • 通过 AXI GPIO 或自定义 IP 控制

71. DisplayPort 控制器 (DP)?能输出几路?

  • UltraScale+ MPSoC 集成 DP TX
  • 支持 1 路 DisplayPort 1.2a(4K@60Hz)

72. MIPI CSI-2 RX 子系统用于什么场景?最大速率?

  • 用于 摄像头输入
  • 最大 4-lane × 1.5 Gbps/lane = 6 Gbps

73. 如何用 PL 端 NRZ 时序驱动 WS2812B?

  • WS2812B 要求:
    • T0H = 0.35 µs, T0L = 0.8 µs
    • T1H = 0.7 µs, T1L = 0.6 µs
  • 100 MHz 时钟,计数器生成精确脉宽
  • 状态机:IDLE → SEND_BIT → NEXT

74. 如何用 PL 端"正交解码"IP 读旋转编码器?

  • 使用 Xilinx Quadrature Decoder IP
  • 输入 A/B 相,输出 count 和 direction
  • 通过 AXI-Lite 读取位置

75. 如何通过 AXI-GPIO 与 DRV8825 驱动步进电机?

  • GPIO[0] = STEP, GPIO[1] = DIR

  • 软件循环:

    复制代码

    c

    编辑

    复制代码
    XGpio_DiscreteWrite(&gpio, 1, 0x02); // DIR
    for (i=0; i<steps; i++) {
        XGpio_DiscreteWrite(&gpio, 1, 0x03); // STEP high
        delay_us(10);
        XGpio_DiscreteWrite(&gpio, 1, 0x02); // STEP low
        delay_us(10);
    }

76. 如何在裸机里写"位置式 PID"控制电机?

复制代码

c

编辑

复制代码
float pid(float setpoint, float feedback) {
    static float err_sum = 0, last_err = 0;
    float err = setpoint - feedback;
    err_sum += err * dt;
    float d_err = (err - last_err) / dt;
    last_err = err;
    return Kp*err + Ki*err_sum + Kd*d_err;
}

77. 如何在 A53 上跑 FreeRTOS?入口在哪?

  • 使用 ARM64 port of FreeRTOS
  • 入口:prvPortStartFirstTask()(汇编)
  • 需关闭 MMU,使用物理地址

78. FreeRTOS 任务状态有哪几种?

  • Ready
  • Running
  • Blocked
  • Suspended

79. 什么是二进制信号量、互斥量、队列集?

  • Binary Semaphore:任务同步(如 ISR 通知任务)
  • Mutex:资源保护,支持优先级继承
  • Queue Set:等待多个队列/信号量中的任意一个

80. 如何避免优先级反转?

  • 使用 Mutex with Priority Inheritance
  • FreeRTOS 中创建 mutex 时指定 queueQUEUE_TYPE_MUTEX

81. 什么是 DDR 碎片?如何借助 mempool 减缓?

  • 碎片:频繁 malloc/free 导致空闲块不连续
  • mempool:预分配固定大小块,避免动态分配

82. 如何用 Vivado "IP Integrator" 自动生成 AXI 外设模板?

  • Create Block Design → Add IP → AXI GPIO / AXI Timer
  • Run Connection Automation
  • Generate Output Products → Export to SDK

83. Xilinx BSP 与裸机"standalone" 驱动差异?

  • BSP:包含板级配置(xparameters.h)
  • standalone:通用驱动库(xuartps.c 等)
  • BSP 依赖 standalone

84. 轮询、中断、DMA 三种 Xilinx 驱动模式资源对比?

模式 CPU 占用 延迟 吞吐 适用
轮询 调试
中断 中速
DMA 高速

85. 如何处理 DMA 超时的"timeout hook"?

在 Xilinx DMA 驱动中注册回调:

复制代码

c

编辑

复制代码
XAxiDma_SetTimeoutHandler(&dma, timeout_handler, NULL);

86. 如何自定义 xilinx_uartps 的接收回调?

复制代码

c

编辑

复制代码
XUartPs_SetHandler(&uart, recv_callback, NULL);
XUartPs_EnableInterrupt(&uart, XUARTPS_IXR_RXFULL);

87. 如何通过 JTAG-SWD 调试 FSBL?

  • 使用 Xilinx SDK Debugger
  • 在 FSBL 项目中设置断点
  • 通过 JTAG 连接(需 DONE 引脚上拉)

88. 断点有哪几种?

  • Software Breakpoint:插入 BKPT 指令
  • Hardware Breakpoint:利用 DBGBCR 寄存器
  • Watchpoint:监控数据地址访问

89. 如何重定向 printf 到 UART-1?

_write() 函数中调用 XUartPs_Send()


90. 如何使用 ITM / TPIU 做 4-bit trace?

  • 配置 CoreSight 组件
  • 使能 ITM Port 0
  • 通过 SWO 引脚输出 trace data

91. 如何用 PMU 测 A53 指令周期?

  • 使能 PMU counter 0 for INST_RETIRED
  • PMCCNTR_EL0

92. 如何配置 Zynq 进入"休眠"与"待机"?

  • Suspend :Linux echo mem > /sys/power/state
  • Standby :调用 XPm_RequestSuspend()

93. 深睡模式下哪些岛能独立存活?

  • RTC domain(含 AWDT、Battery SRAM)
  • R5 TCM(若供电保持)
  • 部分 MIO GPIO(配置为唤醒)

94. 如何测量并优化 PS+PL 整体功耗?

  • 工具:Xilinx Power Estimator, Vivado Power Analysis
  • 步骤
    1. 降低时钟频率
    2. 关闭未用外设
    3. 使用低功耗模式
    4. 优化 PL 逻辑(减少 toggle rate)

95. PCB 上 MIO Bank 的 1.8 V/3.3 V 组怎么分区?

  • Bank 0/1/2/3 各自独立
  • 同一 Bank 内所有 MIO 必须同电压
  • 例如:Bank 1 = 1.8V (UART), Bank 2 = 3.3V (SPI)

96. 什么是去耦电容?PS 端为什么要求 0402 100 nF 距引脚 <2 mm?

  • 去耦电容:滤除高频噪声
  • 0402 100nF:高频响应好
  • <2 mm:减少 ESL,保证瞬态电流供应

97. 高速 GTX/GTH 差分对如何与低速数字区隔离?

  • 3W rule:差分对间距 ≥ 3× 线宽
  • 地平面完整,避免分割
  • 包地处理(guard traces)

98. PL 配置失败常见原因有哪些?

  • Bitstream 与硬件不匹配
  • VCCINT/VCCBRAM 供电不足
  • DONE 引脚未上拉
  • INIT_B 被拉低
  • 时钟不稳定

99. 如何用 SWDT+AWDT 双看门狗提升安全完整性 (SIL)?

  • SWDT 由主程序喂狗
  • AWDT 由 SWDT 服务程序喂狗
  • 若 SWDT 死锁 → AWDT 超时复位
  • 符合 IEC 61508 SIL2/3

100. 在生产现场如何基于 TF-A + U-Boot + OTA 实现 Zynq 固件远程升级?

  1. TF-A 验证下一阶段镜像签名
  2. U-Boot 从网络/TFTP 下载 new_BOOT.BIN
  3. 写入 QSPI Flash 备份区
  4. 更新 boot header 指向新镜像
  5. 重启生效
  6. 支持 回滚机制(若启动失败)

安全:全程 SHA3 + RSA 验签。


总结:以上100问覆盖 Zynq 全栈开发核心知识点,适用于高级嵌入式工程师面试或系统设计参考。如需某一点深入展开,可继续提问。

相关推荐
我送炭你添花3 小时前
可编程逻辑器件(PLD)的发展历程、原理、开发与应用详解
嵌入式硬件·fpga开发
步达硬件4 小时前
【FPGA】电子学习资料(持续更新)
fpga开发
Aaron15885 小时前
电子战侦察干扰技术在反无人机领域的技术浅析
算法·fpga开发·硬件架构·硬件工程·无人机·基带工程
Punchline_c6 小时前
双端口RAM IP核
fpga开发
hexiaoyan82710 小时前
信号处理卡 数据收发卡设计方案:428-基于XC7Z100+ADRV9009的双收双发无线电射频板卡 5G小基站 无线图传
fpga开发·无线图传·9009开发板·xc7z100板卡·视频数据收发卡
范纹杉想快点毕业10 小时前
AI助教初学者问答FPGA芯片基础概念100道问题,适用入门嵌入式软件初级工程师,筑牢基础,技术积累
fpga开发·架构
硅农深芯1 天前
六大核心芯片:MCU/SOC/DSP/FPGA/NPU/GPU 的区别与应用解析
单片机·嵌入式硬件·fpga开发
9527华安1 天前
FPGA纯verilog实现JESD204B协议,基于AD9081数据接收,提供2套工程源码和技术支持
fpga开发·jesd204b·ad9081
FPGA技术实战1 天前
基于XADC IP核的FPGA芯片温度读取设计
网络协议·tcp/ip·fpga开发