4. 主机控制器RTL设计要点:状态机设计、TD管理与FIFO控制逻辑
在USB主机控制器(Host Controller, HC)的RTL实现中,控制传输(Control Transfer)的正确性直接依赖于三个核心模块的设计质量:状态机(FSM)、传输描述符(TD)管理与FIFO控制逻辑。这三个模块相互耦合,任何一个环节的缺陷都可能导致总线挂起、数据错位或协议违规。本节将逐一剖析其设计要点与验证陷阱。
验证警示: 在FPGA验证中,超过70%的控制传输故障可追溯到状态机跳转条件遗漏、TD链表断裂或FIFO空/满标志延迟。RTL设计阶段必须为这三个模块建立独立的断言(Assertion)覆盖。
4.1 状态机设计:IDLE/SETUP/DATA/STATUS
控制传输的状态机通常采用四级流水或四级嵌套结构:IDLE → SETUP → DATA → STATUS。每个阶段对应USB协议中的一个事务(Transaction)。
4.1.1 状态定义与跳转条件
| 状态 | 协议阶段 | 典型跳转条件 | 常见RTL错误 |
|---|---|---|---|
| IDLE | 等待TD有效 | TD_Valid & Channel_Active | 未清除残留状态,导致误触发 |
| SETUP | 发送8字节Setup包 | TX_Complete & ACK_Received | 未等待ACK即跳转,违反协议 |
| DATA | 数据阶段(IN/OUT) | Data_Phase_Done / Error_Detected | DATA0/DATA1切换逻辑缺失 |
| STATUS | 握手阶段(反向方向) | Status_Complete / Timeout | 方向控制错误,导致总线冲突 |
设计要点: 状态机必须支持“错误恢复”路径。当SETUP阶段收到NAK或超时,应返回IDLE并置位错误标志,而非卡死在当前状态。建议使用三段式FSM(状态寄存器、次态逻辑、输出逻辑)以分离时序与组合逻辑。
4.2 TD(传输描述符)管理
TD是主机控制器与软件驱动之间的关键接口。在RTL中,TD通常以链表形式存储在系统内存中,由HC通过DMA引擎读取。TD管理涉及链表遍历、状态回写与中断生成三个核心操作。
4.2.1 TD数据结构与字段定义
// 典型TD结构(32字节对齐)
typedef struct {
uint32_t next_td_ptr; // 下一个TD指针(位[31:5]有效)
uint32_t td_status; // 状态字:完成标志、错误码、数据长度
uint32_t buffer_ptr_low; // 数据缓冲区低32位地址
uint32_t buffer_ptr_high; // 数据缓冲区高32位地址(64位系统)
uint32_t token_info; // Token信息:端点号、方向、DATA0/1、PID
uint32_t reserved[3]; // 保留字段
} td_t;
RTL陷阱: TD链表指针必须按32字节对齐(低5位为0)。如果软件分配了非对齐地址,HC的DMA读取将产生地址错位,导致TD内容解析错误。验证时需构造非对齐地址的边界测试用例。
4.2.2 TD管理状态机
HC内部维护一个TD管理状态机,负责从内存中预取TD、解析字段、启动传输,并在传输完成后回写状态。典型流程如下:
- TD_FETCH:根据当前TD指针从系统内存读取32字节TD数据。
- TD_PARSE:解析token_info字段,确定传输方向、端点、数据切换位。
- TD_EXECUTE:启动控制传输状态机(SETUP/DATA/STATUS)。
- TD_WRITEBACK:传输完成后,将完成状态、实际传输长度、错误码写入内存中的td_status字段。
- TD_NEXT:读取next_td_ptr,若有效则跳转到TD_FETCH,否则产生中断。
4.3 FIFO控制逻辑
FIFO在主机控制器中承担跨时钟域同步与速率匹配的双重角色。控制传输的数据阶段通常使用两个FIFO:发送FIFO(TX FIFO)和接收FIFO(RX FIFO)。
4.3.1 FIFO深度与宽度设计
| 参数 | 推荐值 | 设计依据 |
|---|---|---|
| 数据宽度 | 8位(UTMI接口)或16位(ULPI接口) | 匹配PHY接口位宽 |
| TX FIFO深度 | ≥ 64字节(全速) / ≥ 512字节(高速) | 覆盖最大数据包(64/512字节) |
| RX FIFO深度 | ≥ 64字节 + 4字节(状态信息) | 防止接收溢出 |
| 空/满标志 | 组合逻辑输出 + 1级流水线 | 避免亚稳态,同时保证响应速度 |
4.3.2 FIFO控制状态机
FIFO控制逻辑需要处理以下场景:
- 写使能:仅在FIFO未满时允许写入,否则产生反压(Backpressure)。
- 读使能:仅在FIFO非空时允许读取,否则保持读指针不变。
- 溢出保护:当RX FIFO满时,HC应自动发送NAK,防止数据丢失。
- 帧起始(SOF)同步:在控制传输的STATUS阶段结束后,FIFO指针应复位到初始状态。
验证重点: 构造“FIFO几乎满”场景(如深度-1),验证反压信号能否在1个时钟周期内生效。同时检查“FIFO几乎空”场景下,读使能是否被正确抑制,防止读取无效数据。
4.4 三个模块的协同验证要点
在FPGA验证中,状态机、TD管理与FIFO控制逻辑必须作为一个整体进行测试。以下是推荐的验证清单:
| 验证场景 | 涉及模块 | 预期行为 |
|---|---|---|
| TD链表正常遍历 | TD管理 + 状态机 | 依次执行SETUP→DATA→STATUS,回写完成状态 |
| TD链表断裂(next_ptr=0) | TD管理 | 停止传输,产生中断,不挂起总线 |
| FIFO溢出 | FIFO控制 + 状态机 | 发送NAK,等待FIFO空间释放后重试 |
| 状态机超时 | 状态机 + FIFO控制 | 返回IDLE,置位超时错误,回写TD状态 |
| DATA0/DATA1切换错误 | 状态机 + TD管理 | 设备端丢弃数据包,HC重试或报错 |
验证策略: 建议使用UVM验证环境,为状态机建立覆盖组(Covergroup),覆盖所有状态跳转对;为TD管理建立断言,检查链表指针合法性;为FIFO控制建立时序检查,确保空/满标志在正确时钟周期生效。