简介:面向嵌入式硬件设计、FPGA开发及Zynq平台学习者的一份开发板原理图资料,围绕Xilinx Zynq-7020/Zynq-7000 FPGA开发板展开,可用于理解板级架构、电源树与常用外设接口的硬件连接方式,适合作为原理图阅读、方案参考和设计核对材料。压缩包内为1个PDF文件,整体约417KB,篇幅集中,便于快速检索电源、DDR3、USB、HDMI、以太网、存储与无线等模块。当前已有3669人学习下载,说明其在Zynq开发板硬件入门与参考场景中具有一定关注度。图中按功能划分了整板电源、Zynq芯片供电与配置、DDR3、USB转UART、USB OTG、GPHY、HDMI、连接器、EEPROM与QSPI Flash、SD卡、按键与LED、USB转JTAG以及WiFi/蓝牙等部分,能帮助读者梳理从供电到外设接口的设计思路。对需要对照Zynq-7000开发板做硬件理解、接口核验或原理图二次设计的人来说,具备较直观的参考价值,尤其适合硬件工程师、FPGA学习者及需要做板级调试与接口核对的人员。
1. 拿到一块 Zynq-7020 开发板原理图,先看哪三页
Zynq-7020 开发板原理图摊开来通常有二三十页,前几页是封面和修订记录,中间是电源、PS 外设、PL Bank、配置与调试,最后是连接器和机械尺寸。多数人第一次翻会从头看到尾,看完只记得“板子挺复杂”。真正有效的读法是先锁定三页:电源树页(哪几路电压、谁给谁供电、上电谁先谁后)、PS 端外设页(DDR3、QSPI、SD、以太网挂在哪些 MIO 上)、配置引脚页(MODE、PROG_B、DONE、INIT_B 怎么接)。这三页决定了板子能不能起来、能不能改、改完会不会翻车。写这套图的核对方法,面向的是想抄板做底板、想改一路 IO 电平、或者手上板子不上电要定位问题的硬件和 FPGA 工程师;纯软件视角看这图意义不大,因为绝大部分“跑不起来”的根因都埋在电源和引脚归属里,而不是在代码里。
2. 把电源树拆开核:Zynq-7020 的十几路供电怎么对
2.1 电源树该画成什么形状,先看输入再看负载
原理图上的电源页是最容易被跳过、又最容易出事的一页。它一般由输入保护(保险丝、TVS、防反接)、若干 DCDC 和 LDO、以及一大片去耦电容组成。读的时候不要顺着器件编号读,而是从输入往下游推:先找到 DC 座或排针输入的 5V/12V,标出它经过哪颗 DCDC 变成 5V 中间轨,再由哪几颗 LDO/DCDC 分出 3.3V、1.8V、1.5V、1.0V。
Zynq-7020(XC7Z020)这一颗芯片本身要吃的轨,常见的有这些:PS 内核 VCCPINT 1.0V、PS 辅助 VCCPAUX 1.8V、PS PLL VCCPLL 1.8V、MIO Bank0 的 VCCO_MIO0(多数板子给 3.3V)、MIO Bank1 的 VCCO_MIO1(多数给 1.8V)、DDR 接口的 VCCO_DDR(DDR3 是 1.5V)、PL 内核 VCCINT 1.0V、PL 辅助 VCCAUX 1.8V、BRAM 的 VCCBRAM 1.0V、ADC 的 VCCADC 1.8V。把这些列成一张表,逐条去图上找它的源头器件和负载点,找不全就说明你还没读懂这张图。
| 电源轨 | 典型电压 | 主要负载 | 常见上游 | 核对要点 |
|---|---|---|---|---|
| VCCPINT | 1.0V | PS 内核 | DCDC | 峰值电流按 1A 量级留余量 |
| VCCPAUX / VCCPLL | 1.8V | PS 辅助与 PLL | LDO | PLL 前串磁珠、单独去耦 |
| VCCINT | 1.0V | PL 逻辑 | DCDC | 随逻辑占用变化,别按空载估 |
| VCCAUX | 1.8V | PL 辅助 | LDO/DCDC | 与 VCCPAUX 是否同源要看清 |
| VCCO_DDR | 1.5V | DDR3 IO | DCDC | 与 DDR 颗粒 VDD 是否同源 |
| VCCO_MIO0 | 3.3V | MIO0-15 | DCDC | 决定 QSPI/SD 的电平 |
| VCCO_MIO1 | 1.8V | MIO16-53 | DCDC | 决定以太网 RGMII 电平 |
这张表是后面所有核对工作的索引。表里“是否同源”这一列特别值得盯:有些板子把 VCCPAUX 和 VCCPLL 并在一条 1.8V 上,只靠一颗磁珠隔开,这种设计在实验室能跑,量产批次一致性就差;有些板子把 VCCO_DDR 和 DDR 颗粒的 VDD 分成两路 DCDC,好处是噪声隔离,代价是两路的上电顺序必须一起考虑。
2.2 上电时序与 PS_POR_B、PS_SRST_B 的 RC 取值
电源起来不等于芯片能起来。Zynq-7020 的 PS 有一个上电复位输入和系统复位输入,图上通常标成 PS_POR_B 和 PS_SRST_B,都是低有效。POR 的释放时刻必须晚于所有 PS 供电稳定,SRST 则用于不断电重启外设。绝大多数开发板的做法是用一个 RC 加一颗复位芯片:复位芯片盯住 1.0V 或 3.3V 的电源良好信号,输出经过 RC 延时后接到 PS_POR_B。
RC 取值不是玄学,按公式算就行:t ≈ 1.1 × R × C。10kΩ 配 100nF 大约 1.1ms,47kΩ 配 100nF 大约 5ms。取值要满足两件事:一是大于电源上升时间,二是满足器件手册对 POR 最小低电平保持时间的要求。实际选型时我一般把延时做到 10ms 量级,宁可慢一点,也别让复位在 1.0V 还没稳的时候就松开——这种问题在示波器上看得见,在代码里看不出来,属于典型的“黑匣子”故障。
读图时要顺着 PS_POR_B 这根网络往回追:它连到复位芯片的哪一脚,复位芯片的输入监测的是哪一路电源,有没有测试点,有没有并联手动复位按键。如果图上 PS_POR_B 只挂了一个 10k 上拉和一个按键、没有监测电源,那这块板子在电源缓慢上升的场景下(比如大容量电容、慢启动 DCDC)大概率会偶发不启动,这就是设计层面的隐患,不是焊接问题。
2.3 用脚本把电源网络导成检查表
原理图工具一般能导出网络表或 BOM 的 CSV。手工对几十条网络容易漏,我习惯写个十几行的脚本先把每条电源轨上的器件数、电容数统计出来,缺去耦的轨自然会浮出来。
import csv from collections import defaultdict # netlist.csv 由原理图工具导出,字段:net, refdes, pin, comment rails = { "VCCPINT": 1.0, "VCCPAUX": 1.8, "VCCPLL": 1.8, "VCCINT": 1.0, "VCCAUX": 1.8, "VCCBRAM": 1.0, "VCCO_DDR": 1.5, "VCCO_MIO0": 3.3, "VCCO_MIO1": 1.8, } stat = defaultdict(lambda: {"load": 0, "cap": 0, "other": 0}) with open("netlist.csv", newline="", encoding="utf-8") as f: for row in csv.DictReader(f): net = row["net"].strip().upper() if net not in rails: continue ref = row["refdes"].strip().upper() if ref.startswith("C"): stat[net]["cap"] += 1 # 去耦电容 elif ref.startswith(("U", "Q")): stat[net]["load"] += 1 # 芯片负载 else: stat[net]["other"] += 1 # 电阻、磁珠、测试点等 for net, s in sorted(stat.items()): flag = " <-- 去耦疑似不足" if s["cap"] < 6 else "" print(f"{net:12s} {rails[net]:.2f}V 负载{s['load']:2d} 电容{s['cap']:3d} 其他{s['other']:2d}{flag}")这段代码的逻辑很直接:按网络名归类,按位号前缀区分电容和芯片,最后对电容数量做一次粗筛。参数上阈值设 6 是经验值,一颗 BGA 封装的电源引脚往往有十几二十个,每个引脚配 0.1μF、整条轨再配若干 10μF/100μF 是常见做法,具体数量以器件手册的去耦建议为准。这里输出的不是结论,是给你一份“需要人工再看一眼”的清单——脚本只能发现数量异常,发现不了电容放得离引脚太远。
3. PS 端外设连图:DDR3、QSPI、SD 与以太网挂在哪
3.1 DDR3 的 VREF、ODT 与 Bank 归属怎么读
DDR3 这一块是原理图里最密、也最容易被新手读错的部分。Zynq-7020 的 DDR 接口是专用引脚,不占 MIO,因此在图上独立成一片。读图时先抓四类东西:地址与控制线(A0-A14、BA0-2、CS、RAS、CAS、WE、CKE、ODT、RESET)、数据线(DQ0-31、DQS0-3、DM0-3)、时钟(DDR_CLK_P/N)、以及电源与参考(VCCO_DDR、VREF、VTT)。
VREF 是所有 DDR3 设计的关键点,典型值是 VDDQ/2,也就是 1.5V 的一半 0.75V。图上常见的做法是两个 1kΩ 1% 电阻从 1.5V 分压,中点接 0.1μF 到地,再送到芯片的 VREF 引脚和颗粒的 VREF 引脚。读图时要确认三件事:分压电阻精度是不是 1%、电容有没有、VREF 是不是只从一个点取(不能两头各分一次压,那样两个 VREF 会有偏差)。
ODT 和 DCI 校准电阻是第二个关键点。Zynq 的 DDR 接口有 VRN 和 VRP 两个引脚,外接 240Ω 1% 电阻到地或到 VTT,用于内部阻抗校准。这两个电阻的精度直接影响眼图,用 5% 电阻省下的几分钱,最后会在高速率下调时序上还回来。DDR3 颗粒侧的 ODT 一般由控制器动态控制,但图上仍有 ODT 引脚,需要确认它连到 Zynq 的哪根控制线,以及有没有被错误地固定上拉。
拓扑方面,常见做法是 fly-by 加写均衡,地址控制线菊花链经过每颗颗粒,时钟和 DQS 做差分等长。读图时数一下颗粒位宽和数量:两片 16 位拼成 32 位是最常见的组合,这时两片的数据线各占一半,DQS 也是两对,别把 DQS 和 DQ 的配对关系看串。
| 信号组 | 常见约束 | 图上要确认的点 |
|---|---|---|
| DDR_CLK_P/N | 差分、等长、参考地完整 | 是否串 0Ω 或磁珠、有无端接 |
| DQS0-3 ± | 与对应 DQ 组内等长 | 每对 DQS 对应的 8 根 DQ 是否成组 |
| 地址/控制 | 相对时钟等长 | fly-by 分支长度是否标注 |
| VREF | 0.75V ±1% | 分压电阻精度与滤波电容 |
| VRN/VRP | 240Ω 1% | 是否靠近芯片引脚放置 |
3.2 MIO 分配表与启动模式引脚
Zynq 的 PS 外设不是随便接的,MIO 引脚有固定的功能复用表。原理图上每个 MIO 旁边一般会标“MIOxx / 功能名”,比如 MIO0-1 常做 QSPI 的片选与时钟,MIO40-45 常做 SD,MIO16-27 常做以太网 RGMII,MIO48-49 常做 UART。读图时把这些标注抄成一张表,左边 MIO 编号,右边功能和外设,再补一列“方向与电平”,这张表就是后面核对设备树和约束文件的依据。
启动模式引脚是最容易读漏的一类。Zynq-7020 在 POR 时会采样一组 MIO 引脚决定从哪里启动(JTAG、QSPI、SD、NAND 等),具体落到哪几个 MIO、电平组合是什么,要查对应封装的技术参考手册里的启动模式表,不同文档版本可能标注方式不同。图上这几个引脚通常会接上拉或下拉电阻,读图时要确认:电阻有没有、阻值是多少、有没有被外设共用。有些板子为了省事把启动引脚同时接到 LED 或按键上,上电瞬间外设把电平拉偏,启动模式就错了,现象是“同一张 SD 卡有时能启动有时不能”,非常像玄学。
3.3 用脚本核对 MIO 是否被重复分配
MIO 冲突是抄板改板时的高频错误:两个外设共用了同一个 MIO,或者某个 MIO 在图上同时接了 QSPI 和 GPIO。人工看几十行容易眼花,写个脚本对着自己的分配表查一遍更稳。
import csv from collections import defaultdict # mio_map.csv 字段:mio, func, owner, dir, level usage = defaultdict(list) with open("mio_map.csv", newline="", encoding="utf-8") as f: for row in csv.DictReader(f): usage[row["mio"].strip()].append(row) problems = 0 for mio, items in sorted(usage.items(), key=lambda x: int(x[0].replace("MIO", ""))): owners = {i["owner"] for i in items} if len(items) > 1 and len(owners) > 1: problems += 1 print(f"[冲突] {mio}: " + " | ".join(f"{i['func']}({i['owner']})" for i in items)) for i in items: if i["dir"].strip().lower() not in ("in", "out", "io"): print(f"[方向缺失] {mio} {i['func']}") print(f"共发现 {problems} 处冲突")脚本把每个 MIO 的所有使用者聚在一起,只要出现两个以上不同外设就报冲突,同时检查方向字段有没有填。参数上没有什么可调的,真正要人工判断的是“共用是否合法”:有些 MIO 确实可以分时复用,比如调试阶段用 UART、量产后改成 GPIO,这种要在表里注明“分时”,否则脚本会一直报。我在一个模拟项目里就因为没标分时,被脚本报了七八条假冲突,回头一条条对图花了不少时间——这类工具的价值在于不漏,而不是在于全自动。
4. PL 端 Bank 电压与配置引脚:改一路 IO 电平要动什么
4.1 VCCO 与 IO 标准的对应关系
PL 侧的 IO 按 Bank 分组,每个 Bank 有一个 VCCO 供电引脚,这个电压决定了该 Bank 内所有 IO 能用的电平标准。Zynq-7020 常见的 HR Bank(比如 Bank 34、35)支持 1.2V 到 3.3V,能配 LVCMOS18、LVCMOS25、LVCMOS33,也能配差分标准。读图时先找每个 Bank 的 VCCO 接到哪一路电源,再看这个 Bank 上挂了什么外设,最后反推约束文件里该写什么 IO 标准。
这里有个经典误区:以为 IO 电平可以靠约束文件随便改。实际上约束文件里的 IOSTANDARD 必须和 VCCO 电压匹配,VCCO 是 3.3V 的 Bank 里写 LVCMOS18,工具在实现阶段可能报错,也可能放过但在板子上表现为驱动能力异常或输入判决错误。所以改板子之前,先看原理图上这个 Bank 的 VCCO 是哪一路、能不能改成目标电压、改了以后同一个 Bank 里的其他外设受不受影响。
| Bank 类型 | 常见 VCCO | 可用 IO 标准 | 典型挂载 |
|---|---|---|---|
| HR Bank 34 | 3.3V | LVCMOS33、LVTTL | LED、按键、扩展排针 |
| HR Bank 35 | 1.8V 或 2.5V | LVCMOS18、LVCMOS25 | 摄像头、低速接口 |
| MIO Bank0 | 3.3V | LVCMOS33 | QSPI、SD、UART |
| MIO Bank1 | 1.8V | LVCMOS18 | RGMII 以太网、USB |
跨 Bank 走线也要看一眼。同一个差分对的两个引脚必须在同一个 Bank 内,跨 Bank 的差分对在工具里是布不通的,图上如果画成跨 Bank,那这块板子的这部分功能基本用不了。
4.2 MODE 引脚、PROG_B、DONE、INIT_B 的接法
PL 的配置引脚决定了 FPGA 逻辑怎么被加载。MODE 引脚组在采样时刻决定启动方式(JTAG、主 QSPI、从模式等),PROG_B 是低有效的重新配置输入,INIT_B 是低有效的初始化完成输出,DONE 是配置完成输出。这四个信号在图上通常挤在一小块区域,读图时要逐个确认:上拉或下拉电阻有没有、阻值多大、有没有测试点、有没有被其他电路共用。
常见做法是 MODE 引脚用 4.7kΩ 电阻拉到固定电平,PROG_B 用 4.7kΩ 上拉到 3.3V 并引出一个按键或排针,DONE 通过一颗 LED 加限流电阻指示,INIT_B 上拉后引到排针做调试观察。这些电阻看着不起眼,但 DONE 那一颗 LED 的接法经常出问题:如果 LED 串的限流电阻太小,DONE 引脚被拉走太多电流,配置完成的电平会被拉低,工具报“DONE 未拉高”,板子看起来就是配置失败。
JTAG 侧要确认 TCK、TMS、TDI、TDO 这四根线的上下拉。行业惯例是 TMS 和 TDI 上拉、TCK 下拉,防止链路悬空时进入不确定状态。如果图上这四根线没有任何上下拉,只靠下载器内部电阻,短线上通常能工作,接上长排线或一分多路就很容易识别不到芯片。
4.3 时钟、复位与测试点
PS 侧的主时钟 PS_CLK 一般由一颗 33.333MHz 晶振提供,这颗晶振的负载电容要按晶振规格书选,不是随便抓两个 22pF。图上晶振旁边通常标了 C1、C2 的值,读图时对一下晶振型号的负载电容要求,差太多会导致起振慢或者干脆不起振。PL 侧如果有额外晶振,也要同样核对。
复位和时钟这两块在原理图上往往只有几根线,但它们是“整板不工作”类故障的第一嫌疑人。读图时把时钟和复位网络单独抄成一张小表,标清源头、负载、测试点位置。板子拿到手,先量这两类信号,比盲目量数据线高效得多。
5. 原理图翻车点排查:六个上电才暴露的问题
5.1 晶振不起振,程序永远停在初始化
现象:上电后 JTAG 能连上,但 PS 端程序跑不动,示波器量 PS_CLK 看不到波形或者幅度很小。
原因:晶振负载电容与规格书不匹配,或者晶振离芯片太远、走线被其他信号干扰。也有一种情况是晶振的使能脚悬空,图上没接上拉。
解决:按晶振规格书的负载电容重新算 C1、C2,一般比标称值略小一点更稳;使能脚确认上拉到供电;实在起不来可以先用外部时钟源从 PS_CLK 引脚注入,验证是晶振问题还是芯片问题。这一步能省掉大量瞎猜。
5.2 电源顺序不对,IO 出现倒灌
现象:板子能启动,但某些 Bank 的输入引脚在对面器件未上电时出现漏电,功耗偏高,长时间运行发热。
原因:VCCO 先于 VCCINT 上电,或者两个相连器件的 IO 电源不同步,导致电流从高电平侧灌进未上电侧。
解决:核对原理图上各路电源的使能链,确认上电顺序符合手册建议;在互联的两块板之间加电平转换或串联限流电阻;如果只是调试阶段,先把两块板同时上电规避。这类问题在单板测试时几乎发现不了,联调时才暴露。
5.3 DDR3 校准失败,跑一会就错
现象:DDR 初始化偶尔失败,或者低速率能跑、提高频率后随机报错。
原因:VREF 分压电阻用了 5% 精度、VREF 上没有滤波电容、或者 VRN/VRP 的 240Ω 电阻离芯片太远。
解决:把分压电阻换成 1%、VREF 就近加 0.1μF、校准电阻紧贴引脚放置;同时用示波器看一下 VREF 上的纹波。DDR 这一类问题最容易让人怀疑代码,实际上是模拟前端的事。
5.4 启动模式随机跳变
现象:同一张启动卡,有时能启动有时不能,复位几次就好了。
原因:启动模式引脚被外设共用,上电瞬间外设把电平拉偏;或者上下拉电阻阻值太大,采样窗口内电平没建立。
解决:把启动引脚从外设上断开,改成专用上下拉,阻值降到 4.7kΩ 以内;在图上把启动引脚单独圈出来,作为改板必查项。
5.5 DONE 指示灯把配置拉低
现象:下载器显示配置完成,但 DONE 引脚电压只有 1V 出头,系统不启动。
原因:DONE 脚上串的 LED 限流电阻太小,或者 LED 直接接到地,把 DONE 的驱动能力吃掉了。
解决:换大限流电阻或者用三极管/MOS 管做隔离驱动,DONE 脚只做检测不做负载。这条是纯粹的血泪经验,看图上完全合理,上电才发现。
5.6 排针电平与 Bank 电压不一致
现象:扩展排针接 3.3V 外设工作正常,接 1.8V 外设就通信失败或者烧外设。
原因:排针所在的 Bank VCCO 是 3.3V,但使用者按 1.8V 理解;或者排针跨越了两个不同 VCCO 的 Bank,图上没有明显分隔。
解决:在原理图排针旁标注每个引脚所属 Bank 和 VCCO,改板时把不同电平的引脚物理隔开。这个坑在抄板场景里出现频率极高。
6. 把原理图变成上电调试清单:测试点、万用表和一次实测
图读完了,最后一步是把它变成一张能带在手上的表。我习惯在原理图上先标测试点,没有测试点的网络就用通孔或者排针临时引出来,然后按上电顺序逐项量。下面这张表是照着 Zynq-7020 开发板常见结构整理的,实际项目按自己板子的电源轨增减。
| 顺序 | 测试点 | 预期值 | 工具 | 不达标先查 |
|---|---|---|---|---|
| 1 | 输入 5V/12V | 标称 ±5% | 万用表 | 保险丝、防反接 |
| 2 | VCCPINT | 1.0V ±3% | 万用表 | DCDC 反馈电阻 |
| 3 | VCCPAUX / VCCPLL | 1.8V ±3% | 万用表 | LDO 输入、磁珠 |
| 4 | VCCO_DDR | 1.5V ±3% | 万用表 | DCDC 使能链 |
| 5 | VREF | 0.75V ±1% | 万用表 | 分压电阻精度 |
| 6 | PS_CLK | 33.333MHz 方波 | 示波器 | 晶振负载电容 |
| 7 | PS_POR_B | 上电后由低到高 | 示波器 | RC 取值、复位芯片 |
| 8 | DONE | 配置后高电平 | 万用表 | LED 限流电阻 |
量的时候有个顺序讲究:先静态后动态,先电源后时钟再复位,最后才看数据线。很多人一上来就抓 DDR 的眼图,结果发现 1.0V 只有 0.92V,前面全白做。另一个实用技巧是把示波器的触发设在 PS_POR_B 的上升沿,一次性把电源、时钟、复位三条曲线的相对时序拍下来,比逐条量快得多。
我自己的习惯是:每次改板前把这张表和原理图放在一起过一遍,重点看“预期值”这一列里有没有哪一项我写不出确定数字——写不出来,说明那一块我还没真读懂,改下去就是赌。上面这些坑,有一半是我在类似板子上真踩过的,剩下的是看别人返修报告记下来的。原理图不会骗人,但也不会主动告诉你哪里有问题,它的价值取决于你问它的问题够不够具体。希望帮到你。
本文还有配套的精品资源,点击获取