大家好,继续我们「PCIe 验证每日学习・30 分钟打卡」系列。今天进入链路层核心验证:LTSSM 状态机 + PCIe Cap 链路控制寄存器。

前 11 天核心回顾(1 分钟快速衔接)

  • Day1–2:PCIe 三层架构、物理层、TLP 基础
  • Day3–4:配置空间、Type0/Type1 头
  • Day5–10:中断、BAR、Mem/Cfg 交易、UVM 序列与 Scoreboard
  • Day11:Capability 链表、PCIe Cap(ID=0x10)—— 今天内容的直接基础

今日 30 分钟学习分配

  1. 0–8 分钟:LTSSM 核心状态与链路状态(L0/L0s/L1/Recovery)
  2. 9–18 分钟:PCIe Cap 链路控制寄存器详解 + UVM 配置序列
  3. 19–26 分钟:链路状态 Monitor + 断言检查(验证必用)
  4. 27–30 分钟:必测项 + 小练习

一、LTSSM 核心状态与链路基础(0–8 分钟,通俗无错)

LTSSM = Link Training and Status State Machine链路训练与状态机,是 PCIe 物理层 + 数据链路层最核心的协议自动机,负责链路建立、维持、降功耗、恢复。

1. 必须掌握的 4 个核心状态(入门够用)

  1. Detect上电 / 复位后检测对端设备,判断是否存在 PCIe 链路。
  2. Configuration协商链路宽度(x1/x2/x4/x8…)、速率(2.5GT/s/ 5GT/s/ 8GT/s…)。
  3. L0(正常工作态)链路完全就绪,可正常收发 TLP、DLLP,设备全速运行。
  4. L0s / L1(低功耗态)空闲时自动进入,降低功耗;有流量时快速返回 L0。
  5. Recovery链路信号质量下降、时钟漂移时进入,自动重训练,不复位设备。

2. 验证核心结论

  • 设备正常工作时,必须稳定在 L0;
  • 低功耗模式必须能正常进出 L0s/L1,不丢包、不卡死;
  • Recovery 后必须能回到 L0,不进入死状态;
  • 任何异常不能导致链路无限 Training 或 Down 掉。

3. 链路关键参数

  • 链路速率:Speed (2.5/5/8/16/32 GT/s)
  • 链路宽度:Width (x1/x2/x4/x8/x16)
  • 链路状态:Link Up / Link Down
  • 反向均衡、时钟切换、链路反转等硬件自动功能

二、PCIe Cap 链路控制寄存器(9–18 分钟,详细易懂)

在 Day11 我们知道:PCIe Cap ID = 0x10。它内部包含一组链路控制与状态寄存器(Link Control / Link Status),是软件控制链路的唯一入口。

1. 关键寄存器(入门必记)

  1. Link Control Register(链路控制)
    • 链路速度切换
    • 链路宽度切换
    • 使能 / 禁用 L0s/L1 低功耗
    • 强制进入 Recovery
  2. Link Status Register(链路状态)
    • Link Up/Down 状态
    • 当前速率 Negotiated Speed
    • 当前宽度 Negotiated Width
    • 链路训练完成标志
  3. Slot Capabilities / Slot Control与插槽、热插拔相关,入门先略。

2. UVM 配置序列:读写链路控制寄存器

// 配置链路控制寄存器:使能 L0s 低功耗模式
class pcie_link_ctrl_seq extends uvm_sequence #(pcie_cfg_trans);
    `uvm_object_utils(pcie_link_ctrl_seq)

    pcie_cfg_trans trans;

    // 假设 PCIe Cap 起始偏移为 0x50(由设计决定)
    // Link Control 偏移 = Cap 起始 + 固定偏移
    localparam bit [7:0] LINK_CTRL_OFFSET = 8'h50 + 8'h10;

    function new(string name = "pcie_link_ctrl_seq");
        super.new(name);
    endfunction

    virtual task body();
        // 写链路控制寄存器:使能 L0s
        trans = pcie_cfg_trans::type_id::create("trans");
        start_item(trans);
            trans.cfg_type   = 2'b00;       // Type0 EP
            trans.is_wr      = 1'b1;        // CfgWr
            trans.reg_offset = LINK_CTRL_OFFSET;
            trans.wdata      = 32'h0000_0001; // 使能 L0s
        finish_item(trans);

        `uvm_info("LINK_SEQ", "已使能 L0s 低功耗模式", UVM_LOW)

        // 回读验证
        #100;
        trans = pcie_cfg_trans::type_id::create("trans");
        start_item(trans);
            trans.cfg_type   = 2'b00;
            trans.is_wr      = 1'b0;
            trans.reg_offset = LINK_CTRL_OFFSET;
        finish_item(trans);

        if(trans.rdata[0] == 1'b1) begin
            `uvm_info("LINK_SEQ", "L0s 使能回读成功", UVM_LOW)
        end else begin
            `uvm_error("LINK_SEQ", "L0s 使能配置失败!")
        end
    endtask
endclass

3. 读取链路状态序列(查看 Link Up + 速率宽度)

class pcie_link_status_seq extends uvm_sequence #(pcie_cfg_trans);
    `uvm_object_utils(pcie_link_status_seq)
    pcie_cfg_trans trans;

    localparam bit [7:0] LINK_STS_OFFSET = 8'h50 + 8'h12;

    virtual task body();
        trans = pcie_cfg_trans::type_id::create("trans");
        start_item(trans);
            trans.cfg_type   = 2'b00;
            trans.is_wr      = 1'b0;
            trans.reg_offset = LINK_STS_OFFSET;
        finish_item(trans);

        bit link_up = trans.rdata[0];
        bit [3:0] speed = trans.rdata[4:1];
        bit [3:0] width = trans.rdata[8:5];

        `uvm_info("LINK_STS", $sformatf("Link Up=%b, Speed=%d, Width=x%d",
            link_up, speed, width), UVM_LOW)
    endtask
endclass

三、链路状态 Monitor + 断言(19–26 分钟,验证核心)

LTSSM 是硬件自动状态机,不能靠软件发激励控制,只能靠 Monitor 采样 + 断言检查。

1. 核心验证思路

  • 监测 LTSSM 状态变化
  • 检查链路必须从训练 → 稳定 L0
  • 低功耗进入 / 退出不能卡死
  • Recovery 后必须恢复 L0
  • 禁止出现非法状态跳转

2. 基础断言示例(直接可用)

module pcie_link_assert;
    `include "uvm_macros.svh"
    input clk, rst_n;
    input [3:0] ltssm_state;
    input link_up;

    // 状态编码(与设计一致)
    localparam ST_L0 = 4'h8;

    // 断言:训练完成后必须进入 L0 并保持 Link Up
    property p_link_stable_l0;
        @(posedge clk) disable iff(!rst_n)
        (ltssm_state == ST_L0) |-> ##[1:100] link_up;
    endproperty

    a_link_stable_l0: assert property(p_link_stable_l0) else
        `uvm_error("LINK_ASSERT", "进入 L0 但 Link Up 未置起!")

    // 断言:禁止长期停留在 Configuration/Recovery
    property p_no_training_timeout;
        @(posedge clk) disable iff(!rst_n)
        (ltssm_state inside {[4'h2:4'h7]}) |-> ##[1:2000] (ltssm_state == ST_L0);
    endproperty

    a_no_training_timeout: assert property(p_no_training_timeout) else
        `uvm_error("LINK_ASSERT", "链路训练超时,未进入 L0")
endmodule

四、今日必测项 + 小练习(27–30 分钟)

必测项(可直接进用例清单)

  1. 上电后 LTSSM 正常完成训练,进入 L0,Link Up 置起
  2. 读取 Link Status 寄存器,速率、宽度与设计一致
  3. 配置 Link Control 使能 L0s,回读配置有效
  4. 进入低功耗后能正常返回 L0,不丢链路
  5. 断言无报错,无训练超时

小练习

  1. 说出 LTSSM 最关键的 3 个工作状态
  2. 解释 L0、L0s、L1 的区别
  3. 写一条断言:当链路 Down 时,禁止发送任何 TLP

明日 Day13 预告

【PCIe 验证每日学习・Day13】DLLP 与 ACK/NAK 重传机制基础验证

内容包括:

  • DLLP 作用与类型(ACK、NAK、Flow Control、PM)
  • ACK/NAK 协议原理
  • 重传机制验证思路
  • 简单 DLLP 监测断言与 Scoreboard
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐