这一篇在干嘛?
UG1211 后半部分的精华:时钟族与 DSP 族。时钟是 FPGA 的血液循环——哪个信号能走哪条时钟网络、PLL 怎么配参数,直接决定时序能不能收敛;DSP 原语则是乘累加运算的硬件加速器,做 FIR/FFT/雷达信号处理前必须认识。逻辑与存储族见原语库:DR1(一)。
区域与时钟切换:LCLK、SCLK、MLCLK、IOCLK、GCLK
DR1 时钟体系:先看懂分层再挑原语
UG1211 里时钟相关的原语有 7 个(LCLK、GCLK、MLCLK、SCLK、IOCLK、OSCDIV、PLL),死记端口没有意义,关键是理解 DR1 的时钟网络是分区域、分层级的:
- 全局层:PLL 和全局时钟输入管脚产生的主时钟,覆盖全片,由 BUFG/GCLK 一级分发。
- 多区域层(MLCLK):把时钟输送到上下相邻的两个时钟区域,也能转发给 IOCLK、LCLK。
- 区域层(SCLK / IOCLK / LCLK):SCLK 是全局时钟 GCLK 的分支时钟,内部逻辑资源和 IP 模块都能用;IOCLK 驱动 I/O 列内独立于全局时钟资源的时钟网络,专门伺候高速 IO 串并转换(如 LVDS 接收);LCLK 是 IO 分组上的本地分频器。
- 自由生成(OSCDIV):不依赖任何外部时钟的内部振荡器。
选型口诀:给全片逻辑供时钟走 BUFG/GCLK;时钟只在一个区域内用就下放到 SCLK/MLCLK 减少功耗和偏斜;高速 IO 接口老老实实用 IOCLK;需要特殊频率的分频就用 LCLK。
区域与时钟切换:LCLK、SCLK、MLCLK、IOCLK、GCLK
LCLK:IO 分组上的硬件分频器
DR1_PHY_LCLK 是 PL IO 上的外部时钟分频器,每个 IO 分组有两个。参数很能打:
| 参数 | 可选值 | 说明 |
|---|---|---|
| DIV | ”1”~“8”、“3P5” | 分频系数,支持 1-8 整数分频和 3.5 分频 |
| LCLK | ”BYPASS”/“DIV2T08”/“DIV1”/“GND” | clkout 输出模式 |
| CLKSEL | ”ORG”/“INV” | 输入时钟是否取反 |
| CEMD | ”SYNC”/“ASYNC” | SYNC 时 ce 信号延迟 4 拍才进内部 DFF |
| GSR | ”ENABLE”/“DISABLE” | 全局复位使能 |
一个容易踩的细节(手册注 1):想让 clkout 与分频输出一致,DIV=1 时 LCLK 必须选 “DIV1” 模式,DIV=2~8 时必须选 “DIV2TO8” 模式,配错只会得到旁路直通或接地。分频输出 clkdivout 可以直接供全局时钟网使用,也能驱动逻辑与 IP 资源。
SCLK / MLCLK / IOCLK:区域分发三兄弟
三者端口都极简(clkin/ce/clkout 或 clkin/clkout),差别只在”信号从哪来、能到哪去”:
DR1_PHY_SCLK:GCLK 的分支时钟,逻辑资源和 IP 模块都能驱动。有个DELAY参数(0~3),但手册注明单独调节延时需要配置 DR1_LOGIC_BUFG 结合使用。DR1_PHY_MLCLK:多区域时钟,输入为本地区域的全局时钟输入管脚或本地 PLL 输出;能把时钟送到上下相邻两个时钟区域,也可输出到 IOCLK、LCLK。BYPASS="ENABLE"时输入直通输出。DR1_PHY_IOCLK:驱动 I/O 列内独立时钟网络,支持高速输入/输出接口串并转换(LVDS 接收就靠它)。输入来源可以是本区域 MLCLK、相邻区域 MLCLK、本区域 PLL 输出、区域全局时钟输入管脚;可以驱动本区域所有 IO 块。
GCLK:带无毛刺切换的全局时钟选择器
DR1_PHY_GCLK 是全局时钟缓冲选择器,从两路输入 clkin[2] 里选一路输出,还有无毛刺切换能力——这是它的核心价值。真值表逻辑:cen/seln 都是低有效,cen[0]=0 && seln[0]=0 选 clkin[0],cen[1]=0 && seln[1]=0 选 clkin[1]。
关键端口 drct[2]:配置成 2'b00 时两路输出时钟无毛刺切换(代价是切换过程中输出会丢一个下降沿);2'b11 是普通模式,切换可能出毛刺。参数 PRESELECT(“CLK0”/“CLK1”)定上电默认输出,HOLD(默认 “YES”)定保持期输出高还是低,SEL_TRIGGER 选上升沿还是下降沿采样。

常见坑:手册两条注记都是"不能做"——①两路输入里若有一路是恒定高电平,GCLK 无法正常工作,必须强迫一路为低;②不建议 seln 和 cen 同时使能,可能导致模块工作异常。做双时钟域热备份切换前,先把这两条约束画进设计。
OSCDIV:不吃外部时钟的内部振荡器
DR1_PHY_OSCDIV 是 DR1 内部 OSC 振荡器的分频输出模块——芯片自己产生时钟,参数 DIV(1~128,默认 128)调节分频。端口三个:rstn(低有效复位)、stdby(=1 时钟暂停输出,=0 正常输出)、osc_clk 输出。
典型用途:上电初期的看门狗/状态机时钟、配置流程时钟、低功耗唤醒源。注意它的精度是内部 RC 振荡器水平,别拿去做高精度串口波特率;但”没有外部晶振也能动”这一条,在调试”板子晶振没焊好/时钟没进芯片”类问题时是救命稻草。

PLL:频率、占空比、相位的总调度台
DR1_PHY_PLL 是 DR1 PL 内部的锁相环,能力四件套:输出频率调整、占空比调整、相位调整、动态相位移动。它是全手册最复杂的原语——8 路输出通道(clkc[7:0] 及反相 clkc[7:0]),参数几十个,但日常使用只需抓住骨架:
端口分组:
- 基本组:
refclk参考时钟、pllreset复位(高有效)、lock锁定指示(高有效)、clkc/clkcb8 对输出。 - 动态重配置(DRP)组:
drp_clk/drp_rstn/drp_sel/drp_rd/drp_wr/drp_addr[7:0]/drp_wdata[7:0]输入,drp_rdy/drp_err/drp_rdata[7:0]输出——运行时不重初始化就改 PLL 参数的接口。 - 动态相移(PS)组:
psclk/psclksel[2:0]/psstep/psdown输入、psdone输出——psclksel 选中某一路输出,psstep 上升沿触发左/右移相。 - 辅助组:
pllpd电源开关(高电平关断 PLL)、ssc_en展频使能、clkc_en[7:0]逐通道使能、clkc_rst[1:0]分组复位([0] 管 CLKC03、[1] 管 CLKC46)。

参数骨架(其余按默认):
| 参数 | 作用 |
|---|---|
| REFCLK_DIV / FBCLK_DIV | 输入/反馈分频(1-128),与 VCO 共同决定频率 |
| FRAC_ENABLE + SDM_FRAC | 小数分频使能 + 小数部分(0-4095),做非整数倍频 |
| CLKCx_DIV (x=0~6) | 各输出通道分频(1-128) |
| CLKCx_DUTY50 / CLKCx_DUTY_INT | 占空比 50% 使能 / 精细占空比参数(1-127) |
| PLL_FEED_TYPE | ”INTERNAL”/“EXTERNAL” 内部/外部反馈 |
| LPF_RES/LPF_CAP/ICP_CUR/GMC_GAIN | 环路带宽四参数 |
| DYN_PHASE_PATH_SEL 等动态相移使能 | 开启 PS 组端口功能 |
手册还留了一条重要注记:使用 PLL 时切断输入时钟,VCO 无法完全关闭,会存在最低震荡频率——做时钟门控低功耗设计时别指望”断 refclk = PLL 全停”,要断电请用 pllpd。
实际项目中绝大多数人不会手写这一大坨参数:DR1_PHY_PLL 同时支持原语例化和 IP Generator,在 TD 的 IP Generator 图形界面里配频率更不容易错。手写例化适合脚本化生成或需要精确控制每个通道的场景。
逻辑乘法器 MULT 与 DSP 全家桶
DR1_LOGIC_MULT:带流水选项的独立乘法器
DR1_LOGIC_MULT 是内部乘法器,默认 18×18→36 位。它和 DSP 族的区别是更接近”普通运算符”:位宽参数化(INPUT_WIDTH_A/B、OUTPUT_WIDTH 都 >0 可调),输入输出各自可选寄存器(INPUTREGA/INPUTREGB/OUTPUTREG,默认全 ENABLE),复位模式可选(SRMODE “ASYNC”/“SYNC”),还能用 IMPLEMENT 参数指定实现方式:“AUTO”(工具自己定)、“DSP”(强制用 DSP 单元)、“GATE”(强制用 LUT 门电路搭)。

端口里 cea/ceb/cepd 是 A 口、B 口、乘积输出的片选(高有效),rstan/rstbn/rstpdn 是对应复位(低有效)。手册时序图旁注了一句要害:输入或输出加寄存器,输出会延迟一个时钟周期——三级寄存器全开就是经典的乘法器两级流水,做 FIR 时正好用来凑时序。它只支持原语例化,IP Generator 里没有。
DSP 族:把 DSP 单元拆开用
DR1 的 DSP 硬单元被拆成 6 个可独立例化的原语,全是”端口小、无(少)参数”的风格,多数还支持 IP Generator:
| 原语 | 功能 | 关键端口 |
|---|---|---|
| DR1_PHY_DSPADD | 27 位加/减法 | opctrl[0] 加法器使能、opctrl[1] 选 sum=a+b 或 a-b |
| DR1_PHY_DSPLOGIC | 54 位逻辑运算 | opctrl[3:0] 选 xor/xnor/and/or/nand 等九种,opctrl[4] 控制宽位异或 wxor |
| DR1_PHY_DSPMULT | 27×18→45 位乘法 | opctrl[0] 使能、opctrl[1] 选 xx 或 xy 模式 |
| DR1_PHY_DSPREG | 1~54 位寄存器 | WIDTH/RSTMODE(SYNC·ASYNC)/CLKMUX/CEMUX/RSTMUX |
| DR1_PHY_DSPMREG | 带动态级数选择的寄存器 | opctrl 选 0/1/2 级寄存输出 |
| DR1_PHY_DSPTADD | 54 位三输入加减法器 | x/y/z 三口 + 进位,opctrl[3:0] 定符号组合 |


两个容易忽视的点:
- DSPMULT 的平方模式:opctrl[1]=0 时执行
p = x[17:0]*x[17:0](x 自乘),=1 时执行p = x[26:0]*y[17:0]。求模长平方(如 |I+jQ|²)这类运算直接省一个乘法器。 - DSPMREG 的动态流水:
DYNAMIC_DATA参数定 0/1 级基准,运行时 opctrl 还能在”2 级”与”0 或 1 级”之间切换——同一电路动态改变流水深度,适合可变延迟的数据通路。
DSPTADD:三输入加减法器与级联
DR1_PHY_DSPTADD 是 DSP 单元里的三输入加/减法器,54 位 x/y/z 三口同时进位相加,一颗顶普通加法器三颗。opctrl[3:0] 组合出 16 种符号方案,最常用的几种:
| opctrl[3:0] | sum |
|---|---|
| 4’b0000 | x+y+z+ci |
| 4’b0010 | -x+y+z+ci |
| 4’b0100 | x-y+z+ci |
| 4’b0110 | -x-y+z |
| 4’b1000 | x+y-z+ci |
(4’b0001/0101/1001/1101 等奇数编码则是上下 27 位分段独立相加——一颗 DSP 当两颗 27 位加法器用。)

它还带一组 _special 备用输入(x1_special/y1_special/z1_special/ci_special),由 opctrl[8:5] 在运行时动态切换,配合参数 X1_EXTEND(符号位扩展)、Y1_ROUND(换成内置常数 RND_CONST)、Z1_SHIFT(右移 17 位补符号)、CI_INVERT(取反)做预处理——这些正是乘累加流水线里”对齐/舍入”步骤的硬件化。输出侧 co 进位与 ci 构成快速进位链,手册注明只能在 TU(DSP 单元)与 TU 之间直连级联;overflow/underflow 溢出标志的检测位置由 USE_OVERFLOW(“S0”~“S53”)参数指定,opctrl[4] 选择使能 co 还是使能溢出标志。
片上 ADC:逐次逼近型外设
DR1_PHY_ADC 是 DR1 FPSoC 内嵌的逐次逼近型 ADC,不再只是 PL 逻辑,而是一个带 APB 总线接口的外设。理解它的关键是端口分四组:
- APB 组:
adc_pl_pclk/paddr/psel/penable/pwrite/pwdata/prdata/pready——CPU 或 APB master 通过寄存器读写控制 ADC(16 位数据线,8 位地址线)。 - Direct 组:
adc_soc(启动转换,高有效,需寄存器位 REG_ADC_SOC_SEL=1)、adc_sel_res[2](分辨率 6/8/10/12bit)、adc_sel_diff(单端/差分)、adc_sel_channel[3]、adc_sel_ref(内部/外部基准)等——绕过 APB 直接由 PL 逻辑控制。 - 输出组:
adc_eoc(单通道转换结束)、adc_eos(一次序列转换结束)、adc_pob[12]并行数据、adc_sob串行数据、adc_busy、adc_channel[3]/adc_muxaddr[3](供外部多路复用器的通道地址)、adc_interrupt_pl。 - 模拟输入组:
adc_vauxp_n/vauxn_n差分对通道 015,外加 vp/vn 专用通道(channel_sel 的 5’d05’d15 选 vaux、5’d16 选 vp/vn)。
仿真相关的参数有三个:VREF(外部输入电压值,默认 “1.25”)、FILE_PATH(外部输入的模拟数据文件——可以用文件喂波形仿真 ADC 行为)、CHANGE_CLK(模拟数据切换频率,默认 1000kHz)。

应用定位要摆正:SAR 型 ADC 采样率不高(相对高速数据转换器),适合监控电压、读温度传感器、做简单按键/电位器采样这类慢速任务。需要高速采集时该外接专用 ADC 芯片走 LVDS/SPi 接口,别为难片上这个。它支持原语例化和 IP Generator 两种用法,图形界面配置通道序列更直观。
通关标准:
- 能画出 DR1 时钟分层图(PLL/GCLK → MLCLK → SCLK/IOCLK/LCLK),并说出每个新设计里时钟走的是哪条网络。
- 能配置 PLL 完成”50MHz 晶振 → 100MHz 系统时钟 + 200MHz DDR 参考时钟”的输出分配,并解释 lock 信号的用途。
- 能用 DSPADD/DSPMULT/DSPTADD 搭出最简乘累加结构,说出 IMPLEMENT=“DSP”/“GATE” 的取舍。
自测:需要把系统从 100MHz 参考时钟动态切到备用 125MHz 时钟且切换瞬间不允许输出毛刺,用哪个原语、怎么配?
用 DR1_PHY_GCLK:两路时钟接 clkin[2],drct 配成 2’b00 启用无毛刺切换模式(切换时输出会丢一个下降沿,这是正常代价);PRESELECT 定上电默认路,SEL_TRIGGER 定采样沿。注意两路输入不能有一路恒为高,也不建议 seln 与 cen 同时使能。
自测:板上没有外部晶振也能让一段状态机跑起来吗?
可以。用 DR1_PHY_OSCDIV:内部 OSC 振荡器经 DIV(1~128)分频后从 osc_clk 输出,stdby=0 正常输出、rstn 低有效复位。但它精度有限,只适合看门狗、低速状态机、唤醒时钟,不能当精确波特率时钟。
自测:18×18 有符号乘法想两级流水并强制用 DSP 资源实现,用哪个原语、哪些参数?
DR1_LOGIC_MULT:INPUTFORMAT(“SIGNED”),INPUTREGA/INPUTREGB/OUTPUTREG 全开 “ENABLE”(各加一拍,输出延迟一个时钟周期形成流水),IMPLEMENT(“DSP”) 强制映射到 DSP 单元而非 LUT 门电路(“GATE” 则相反,省 DSP 用逻辑)。
自测:DSPTADD 的 opctrl=4'b0001 和 4'b0000 有什么区别?
4’b0000 是 54 位全宽三输入相加 sum=x+y+z+ci;4’b0001 是把 54 位拆成上下两个 27 位各自独立相加(sum[26:0]=x[26:0]+y[26:0]+z[26:0],sum[53:27]=x[53:27]+y[53:27]+z[53:27]),等于一颗 DSP 同时做两个独立 27 位加法。
自测:想用片上 ADC 轮询采样 4 个外部电压通道,PL 逻辑直接控制不走 APB,启动转换用什么信号?
用 Direct 端口的 adc_soc(高有效启动,前提是寄存器位 REG_ADC_SOC_SEL 已置 1),通道经 adc_channel_sel_x 选择,每通道转换结束 adc_eoc 拉高、整轮序列结束 adc_eos 拉高,12 位结果从 adc_pob 读出。