这一篇在干嘛?

这是 UG1318 系列的第 1 篇,覆盖原书第 1 章(简介)和第 2 章前半部分(PCS 寄存器的时钟/复位/数据通路部分)。寄存器手册最忌讳从第一页逐位背到最后一页——正确的打开方式是先建立”地图”,再在需要时按图索骥。同系列第 2 篇见 PMA 与 Common 寄存器实战

哪些器件有 HXT,这本手册管多大范围

寄存器空间怎么组织:基地址地图

三种读写模式与 _ovr/_sw 软件覆盖套路

PCS 时钟控制:TX_CLK_CTRL_0 与 RX_CLK_CTRL_0

PCS 复位控制:TX_RST_CTRL_0 与 RX_RST_CTRL_0

数据宽度与编码:DATA_WIDTH 与 ENC_EN

PRBS 误码测试:LBERT 系列寄存器

接收对齐:RX_ALIGN 系列 COMMA 寄存器

哪些器件有 HXT,这本手册管多大范围

HXT 是 PH1P 系列里的高速收发器(SerDes)硬核,用来跑 PCIe、千兆网、JESD204 之类的高速串行协议。但不是每颗 PH1P 都带它,原书开篇的表 1-1 说得很清楚:

系列器件是否有 HXT
PH1P100PH1P100SBG676支持
PH1P100PH1P100SBG677支持
PH1P50PH1P50SBG484支持
PH1P35PH1P35MBG484 / PH1P35MDG324 / PH1P35MHG324无 HXT

也就是说 PH1P100 和 PH1P50 有 HXT,PH1P35 全系没有。原书还专门声明了一句:这份文档”仅供参考,不作为正式的 HXT 应用指导文件”,并且不随数据手册同步更新——意思是你做正式设计时,IP 向导生成的配置才是权威,这本手册是给你查寄存器、做调试用的参考书。

寄存器空间怎么组织:基地址地图

HXT 的所有寄存器共享一个 32 位地址空间,其中高 16 位基地址固定为 0x0000,低 16 位用来区分模块。原书表 1-2 是全手册最重要的地图:

寄存器基地址[15:8]
COMMON0x41
LANE 0 PCS0x00~0x01
LANE 0 RX PMA0x02~0x03
LANE 0 TX PMA0x04
LANE 1 PCS0x10~0x11
LANE 1 RX PMA0x12~0x13
LANE 1 TX PMA0x14
LANE 2 PCS0x20~0x21
LANE 2 RX PMA0x22~0x23
LANE 2 TX PMA0x24
LANE 3 PCS0x30~0x31
LANE 3 RX PMA0x32~0x33
LANE 3 TX PMA0x34

从这个表能看出三层结构:

  1. HXT 一个 quad 包含 4 个 lane,lane 编号 0~3,每个 lane 占据一个”百位段”(0x0x、0x1x、0x2x、0x3x)。
  2. 每个 lane 内部又分三层:PCS(协议层,做编码/对齐/PRBS 等)、RX PMA(接收物理层,做均衡/CDR/PLL)、TX PMA(发送物理层,做驱动/FFE/PLL)。
  3. COMMON 是四个 lane 共享的部分(0x41 段),放参考时钟、公共 PLL(QPLL/CMN PLL)、阻抗校准 ZCAL 这些全 quad 共用的资源。

一个常用的记忆技巧:PCS 区寄存器地址都在 0x0000x1BF 之间(lane0),RX PMA 在 0x2000x328(lane0),TX PMA 在 0x400~0x480(lane0),Common 在 0x4100 以后。手册正文里给出的所有 ADDR 都是 lane0 的地址,其他 lane 只需把第二位换成 lane 编号(如 lane2 的 PCS TX_CLK_CTRL_0 就是 0x020 + 0x0 = 0x200 段内的对应偏移——准确说按表 1-2 换算基地址即可)。

三种读写模式与 _ovr/_sw 软件覆盖套路

原书声明每个寄存器字段属于三种读写模式之一:

R/W:可读可写寄存器
R   :只读寄存器
W   :只写寄存器
  • R(只读):典型如各种状态寄存器 *_STS,例如 TX_PI_STS[7]tx_pi_lockRX_ALIGN_STS[7]rx_wordaligned。这些是硬件的真实状态,只能读不能写,调试时靠它们判断链路状态。
  • W(只写):典型是各种”触发脉冲”字段,例如 TX_LBERT_ERR_TRIG[0]tx_err_trigger_pulseRX_LBERT_ERRCNT_LATCH[0]rx_pg_error_rd_pulse。写 1 触发一个动作(自清零),用于”抓一拍当前计数”这类操作。
  • R/W(可读可写):绝大多数配置寄存器都是这类。

全手册还有一个反复出现的设计套路,必须先看懂,后面每个模块都会遇到。很多接口信号(复位、时钟使能、状态值)既由硬件端口控制,也允许软件接管,于是出现成对的字段:

xxx_ovr:软件覆盖使能(1 = 软件说了算)
xxx_sw :软件值(ovr=1 时才生效)

TX_CLK_CTRL_0[31:30] 为例:tx_pma_clk_en_ovr 置 1 后,tx_pma_clk_en_sw 的值才被硬件采用;ovr 为 0 时时钟使能听端口信号的。TX_RST_CTRL_0[20:16]tx_reset_ctl_ovr[4:0][12:8]tx_reset_ctl_sw[4:0] 也是同一逻辑,只是这次覆盖的是 5 路复位信号(tx_reset / tx_pma_reset / tx_pcs_reset / tx_pcsfifo_reset / tx_userrdy)。

常见坑:

只写 xxx_sw 不写 xxx_ovr 是最常见的错误——ovr 为 0 时 sw 值根本不生效,你会在板子上发现”写了没反应”。反过来,调试完记得把 ovr 清回 0,否则端口信号(例如 IP 核输出的复位序列)会被你软件值一直压着,链路行为会很诡异。

PCS 时钟控制:TX_CLK_CTRL_0 与 RX_CLK_CTRL_0

PCS 层的时钟管理集中在两个寄存器里,ADDR 分别是 0x0(TX)和 0x100(RX,lane0)。

TX_CLK_CTRL_0 的关键字段:

Bit字段作用
31:30tx_pma_clk_en_ovr / _swTX PMA 输出时钟使能的软件覆盖
29:28tx_usrclk_sel用户时钟选择:00=rx_usrclk,01=rx_xclk,10=tx_usrclk_lb,11=tx_usrclk_in
27:26tx_outclk_pre_sel输出到 fabric 的 pre 时钟源:00=clk20_pre,01=clk16_pre,1X=clk33_pre
20:16tx_clk25mdiv从 txpllrefclk 分频产生 25MHz 时钟
14:10tx_outclk_divpre 时钟分频比:0=不分频,1=÷2,2=÷3……
9tx_refclk_sel参考时钟选 ref0_clk_p/n 还是 ref1_clk_p/n

RX_CLK_CTRL_0 结构类似但字段更多,几个值得记住的:

Bit字段作用
31:24rx_outclk_div_en / rx_outclk_divRX 输出时钟分频使能与分频比(0=÷1,1=÷2……)
19:16rx_outclk_sel输出时钟源:低 2 位选 CDR 时钟(C20/C16/C33),高 2 位选 PLL refclk 或其分频
12:8rx_clk25mdiv从 133MHz 振荡器或参考时钟分频出校准时钟,手册建议典型值 5’d5
1rx_refclk_selRX 参考时钟选 refclk0 或 refclk1
0rx_sysclk_sel系统时钟源:0=参考时钟,1=内部振荡器时钟

读这两个寄存器的正确姿势不是背每一位,而是回答三个问题:这路时钟从哪来(_sel 字段)、要不要分频(_div 字段)、软件要不要接管(_ovr 字段)。例如排查”fabric 侧时钟频率不对”,就先看 rx_outclk_sel 选了哪个源、rx_outclk_div 分了几。

PCS 复位控制:TX_RST_CTRL_0 与 RX_RST_CTRL_0

ADDR 0x4(TX)和 0x104(RX)。这两个寄存器结构几乎镜像,控制 5 路复位信号的软件覆盖:

_reset_ctl_ovr[4]:tx/rx_userrdy        软件覆盖
_reset_ctl_ovr[3]:tx/rx_pcsfifo_reset  软件覆盖
_reset_ctl_ovr[2]:tx/rx_pcs_reset      软件覆盖
_reset_ctl_ovr[1]:tx/rx_pma_reset      软件覆盖
_reset_ctl_ovr[0]:tx/rx_reset          软件覆盖
_reset_ctl_sw [4:0]:对应 5 路的软件值(ovr=1 时生效)

此外还有一组直接软件复位字段,不经过复位状态机、直接拉住对应子模块,低有效:

字段(TX 侧)作用
tx_pcs_piso_sw_rstn(bit3,默认 1)直接复位 TX PISO
tx_buf_sw_rstn(bit2,默认 1)直接复位 TX FIFO

RX 侧对应的还有 rx_pcs_sipo_sw_rstn、rx_pcs_buf_sw_rstn、rx_pcs_sw_rstn、rx_eye_sw_rstn、rx_dfe_sw_rstn(RX_RST_CTRL_0[5:0],默认全 1 即不复位)。另有 resetsel_sw(TX bit4)选择复位模式:1=sequential(顺序模式),0=single(单次模式)。

还有一个跨 lane 的重要位:TX/RX_RST_CTRL_0[24] 的 tx/rx_bypass_cmn_pll。置 1 表示旁路公共 PLL,lane PLL 直接用参考时钟;置 0 表示启用 CMN PLL,lane PLL 可以用它的输出时钟做参考。

数据宽度与编码:DATA_WIDTH 与 ENC_EN

这一组寄存器决定”一拍传多少位、字节序怎么摆”。

TX_DATA_WIDTH(ADDR 0xC)核心字段:

Bit字段取值
7:0tx_data_width接口位宽:16/20/32/40/64/80
9:8tx_internal_datawidth内部位宽:00=2 字节,01=4 字节,10=8 字节
31:29tx_data_bitrev_en / tx_data_byterev_en / tx_hdr_bitrev_en符号内位反转 / 符号反转 / 头部位反转

RX_DATA_WIDTH(ADDR 0x108)字段几乎相同(rx_data_width、rx_int_datawidth),取值一样支持 16/20/32/40/64/80。

常见坑:

TX 和 RX 的位宽必须与协议匹配且两端一致(比如 64b66b 场景常配 64/80 位宽 + 8 字节内部宽度)。只改一边会出现 gearbox 或 FIFO 溢出,现象是 TX_PCSFIFO_STS 里的 wr_full / halffull 标志置起。

TX_ENC_EN(ADDR 0x10)管 8b10b 编码器的字节/位交换:bit7~4 分别控制编码器输出字节交换、输出位交换、输入字节交换、输入位交换;RX_ENC_EN(ADDR 0x10C)则对应解码侧,另有 bit15:8 的 rx_dec_kcode_edb_reg 配置 K 码错误标志字符(默认 8’b11111110),以及 PCIE 模式和解码输出的交换位。这些交换位是为适配”数据低位在前还是高位在前”的协议习惯准备的,一般用 IP 默认值,出问题时才回头查。

LANE_PROTOCOL(ADDR 0x8)只有一个有效位 bit7 pcie_lane_en:1=lane 工作在 PIPE 协议(PCIe),0=GPCS 模式。这个位决定了部分寄存器(如 PCIE_EQ)是否有效。

PRBS 误码测试:LBERT 系列寄存器

LBERT(linear feedback BERT)是 HXT 自带的伪随机码型发生/校验器,是调试串行链路误码率最常用的手段。TX 侧和 RX 侧各有一套,加上 C16(PMA 内 16 位通路)各一套,共四组。

TX_LBERT_CTRL(ADDR 0x20)关键字段:

Bit字段作用
7:4tx_pg_mode码型选择:0000=正常数据,0001=PRBS31,0010/0011=PRBS23-0/1,0100=PRBS16,0101=PRBS15,0110=PRBS11,0111=PRBS9,1000=PRBS7,1001=固定码型(由 TX_LBERT_PATTERN_0/1 给出)
10:8tx_pg_data_width与内部位宽对应:16/20/32/40/64/80 位
2tx_swapMSB/LSB 模式选择
1tx_invert数据极性反转
0tx_pg_sw_rstn发生器复位(默认 1 即不复位)

TX_LBERT_ERR_TRIG(ADDR 0x24)只有一个 W 位 tx_err_trigger_pulse——写 1 触发一次误码注入(自清零)。这个功能在验证你的误码计数器是否真的在工作时非常好用:故意注入错误,看接收端计数是否增加。

RX 侧 RX_LBERT_CTRL(ADDR 0x160)与 TX 成对,bit7:4 rx_pg_chk_mode 同样是 PRBS 码型选择,多出的 bit16 rx_pg_adjust_en 决定校验器”每拍数据都当种子重新同步”(1)还是”只用初始种子、整个比较过程不重同步”(0)——前者适合自由跑随机数据,后者适合严格误码统计。bit24 是 W 位的比较启动触发。

误码计数的读取是”两步式”:

1. 向 RX_LBERT_ERRCNT_LATCH(0x164)写 1:
   触发读脉冲,硬件把当前误码计数锁存出来(自清零)
2. 读 RX_LBERT_ERR(0x168):
   32 位 rx_pg_error_cnt 即内部数据通路的误码计数

C16 一套同理:TX_C16_LBERT_CTRL(0x44)、RX_C16_LBERT_CTRL_0(0x170)、计数在 RX_C16_LBERT_ERR(0x178)。RX_C16_LBERT_CTRL_0[2]rx_c16_pg_bert_bit_gran 可以选误码粒度是按位(1)还是按 8 位符号(0)。

常见坑:

TX 端 pg_mode 和 RX 端 chk_mode 必须选同一种 PRBS 码型,否则校验器永远失配,误码计数狂飙,你会误以为链路质量差。另外 *_sw_rstn 默认值是 1(不复位),如果你在配置前手滑写了 0,发生器/校验器会被一直按在复位上。

接收对齐:RX_ALIGN 系列 COMMA 寄存器

8b10b 协议(如 PCIe Gen1/2、Gigabit Ethernet)靠 K28.5 COMMA 字符做字节对齐。PCS 层的对齐功能由一组寄存器控制:

RX_ALIGN_EN_CTRL(ADDR 0x120):

Bit字段作用
0rx_wordalign_en字对齐总使能(默认 1)
1rx_pcommaalign_enPCOMMA 对齐使能(默认 1)
2rx_mcommaalign_enMCOMMA 对齐使能(默认 1)
3rx_aligncomma_doublePCOMMA+MCOMMA 双对齐
5rx_alignmcomma_detMCOMMA 检测使能
4rx_alignpcomma_detPCOMMA 检测使能
16rx_align_slide手动滑动模式使能
25:24rx_slidemode滑动方向:00 不移,01 左移,10 右移
15rx_alignen_qualify对齐指示输出加严质量控制(v1.1 新增)

RX_ALIGN_COMMA(ADDR 0x128)定义 COMMA 的具体数值:bit25:16 是 MCOMMA 值,bit9:0 是 PCOMMA 值,默认都是 10’b0011111010 / 1100000101(即 K28.5 的两种极性)。RX_ALIGN_COMMA_MASK(ADDR 0x124)的低 10 位是掩码(默认全 1,即 10 位全比较),高 16 位分别是无效/有效 COMMA 计数阈值。

对齐结果在 RX_ALIGN_STS(ADDR 0x12C):

bit7 rx_wordaligned:字对齐完成标志(R)
bit6 rx_wordrealign :重新对齐事件标志(R)
bit5:0 rx_align_sel_o:COMMA 在输入数据中的位置指示(R)

最后提一下 SKIP/弹性缓冲一组:RX_SKIP_CTRL(0x130)使能 rate-matching FIFO 并定义匹配序列(1/2/4 符号匹配、是否比较 disperr 等),RX_SKIP1/2_PATTERN1/2(0x134~0x140)定义跳过序列的具体字符,RX_SKIP_MARK(0x144)设定弹性缓冲的高/低水位门限(默认 24/8),状态在 RX_SKIP_STS(0x148,含 underflow/overflow 标志)。PCIe 等协议要求周期性插入 SKIP 集合来吸收时钟 ppm 差,这些寄存器就是配置”遇到什么序列就删/补、缓冲水位控制在什么范围”。

通关标准:

  • 能画出 HXT 寄存器地图:4 个 lane × (PCS + RX PMA + TX PMA)+ COMMON,并说出 lane0 各层基地址段。
  • 看到 _ovr/_sw 字段对,能说出”先置 ovr 再给 sw”的两步操作。
  • 能独立配置一次 PRBS31 环回误码测试:TX 选码型、RX 选同码型、启动比较、latch 后读误码计数。