典型总线协议场景设计:AXI、APB、AHB 的设计要点
做验证这些年,打交道最多的就是总线协议。AXI、APB、AHB,这三兄弟几乎出现在每一个 SoC 项目中。说实话,刚入行那会儿,我觉得能把协议背下来就够用了。后来踩了不少坑才明白——协议是死的,场景是活的。今天我就把这三类总线场景设计的核心要点掰开揉碎,跟你聊聊。
一、AXI 协议场景设计:高带宽、乱序、突发
AXI 是 AMBA 家族里的“大哥”。它支持独立地址/数据通道、乱序传输、突发传输。说白了,就是为高性能场景准备的。
1. 通道独立性验证
AXI 有五个通道:读地址、读数据、写地址、写数据、写响应。每个通道都是独立的。我见过不少验证工程师只盯着数据通道,结果地址通道的握手信号出了问题,仿真跑得飞起,上板就挂。
举个例子,写地址通道的握手:
// 地址通道握手
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
awvalid <= 1'b0;
awaddr <= 'b0;
end else begin
// 随机延迟 VALID 信号
if (awready && awvalid) begin
awvalid <= 1'b0;
end else if ($urandom_range(0, 3) == 0) begin
awvalid <= 1'b1;
awaddr <= $urandom;
end
end
end
2. 乱序传输场景
AXI 支持乱序,这是它和 AHB 最大的区别。每个事务都有 ID 标签,从设备可以按任意顺序返回数据。
我遇到过一个问题:DUT 只支持顺序返回,但验证环境里随机生成了乱序 ID。结果仿真一直报错,排查了两天才发现是 VIP 配置问题。所以,乱序场景一定要分两种情况测:
- 同 ID 乱序:同一个 ID 的事务,数据可以乱序返回
- 不同 ID 乱序:不同 ID 的事务,完全独立处理
3. 突发传输边界
AXI 的突发传输有地址对齐要求。比如 4KB 边界不能跨越。这个坑我踩过——有一次验证环境里生成了一个跨越 4KB 边界的突发,DUT 直接死锁了。
验证时一定要覆盖:
- 突发起始地址刚好在边界上
- 突发长度刚好跨过边界
- INCR 和 WRAP 模式的边界行为
二、APB 协议场景设计:简单、低功耗、两周期
APB 是“小弟”,接口简单,就几个信号。但越简单的东西,越容易在细节上翻车。
1. 状态机转换
APB 的状态机只有三个状态:IDLE、SETUP、ACCESS。但转换条件必须严格按协议来。
我记得有一次,DUT 在 SETUP 状态只待了一个周期就跳到了 ACCESS,但协议要求至少一个周期。仿真没报错,因为验证环境没检查状态停留时间。后来上板测试,APB 接口偶尔读回错误数据。
状态机验证的典型场景:
// APB 状态机检查
property p_apb_setup_hold;
@(posedge pclk)
disable iff (!preset_n)
(psel && !penable) |=> (psel && penable)[=1];
endproperty
2. 无等待状态 vs 等待状态
APB 支持从设备插入等待(通过 PREADY 信号)。但很多简单的外设不支持等待,PREADY 直接拉高。
验证时要注意:
- 从设备支持等待时,要测 PREADY 随机拉低
- 从设备不支持等待时,要确保 PREADY 永远为高
- 混合场景:系统中既有支持等待的从设备,也有不支持的
3. 错误响应场景
APB 有 PSLVERR 信号,用于指示传输错误。但很多验证环境只测正常传输,忽略了错误场景。
我建议至少覆盖:
- 访问不存在的地址空间
- 写保护区域
- 从设备内部错误
三、AHB 协议场景设计:流水线、突发、拆分
AHB 是“二哥”,比 APB 复杂,比 AXI 简单。它最大的特点是流水线传输和拆分传输。
1. 流水线传输
AHB 的地址阶段和数据阶段是重叠的。当前事务的数据阶段,就是下一个事务的地址阶段。这个特性很容易被忽略。
我见过一个案例:验证环境里地址和数据之间插了随机延迟,结果 DUT 的地址采样逻辑出了问题。因为 DUT 假设地址阶段一定比数据阶段早一个周期。
2. 突发传输终止
AHB 支持四种突发类型:SINGLE、INCR、WRAP、INCR4/8/16。其中 INCR 类型(不定长突发)的终止条件最容易出问题。
验证场景设计:
- 突发在中间被 HREADY 拉低打断
- 突发被 HRESP 的 SPLIT 或 RETRY 打断
- 突发在最后一个 beat 被终止
3. 拆分传输(SPLIT)
SPLIT 是 AHB 独有的特性。从设备可以告诉总线:我还没准备好,你先去处理别的事务。等准备好了再通知总线。
这个场景验证起来比较麻烦。我建议:
- 先验证 SPLIT 的基本流程:请求 → SPLIT → 重试 → 完成
- 再验证多个 SPLIT 事务的乱序完成
- 最后验证 SPLIT 和 RETRY 的混合场景
四、三种协议的场景对比
做项目时,经常需要同时验证这三种协议。我整理了一个对比表,方便你快速参考:
| 特性 | AXI | AHB | APB |
|---|---|---|---|
| 通道数 | 5(独立) | 2(地址+数据) | 1(合并) |
| 传输模式 | 乱序、突发 | 流水线、突发 | 两周期 |
| 等待机制 | READY 信号 | HREADY + SPLIT | PREADY |
| 典型场景 | DDR、DMA | SRAM、桥接 | 寄存器、外设 |
| 验证难点 | 乱序、ID 管理 | SPLIT、流水线 | 状态机时序 |
五、知识体系总览
下面这张图是我自己总结的三种协议场景设计框架。每次做新项目,我都会对着这张图检查一遍,确保没有遗漏。
嗯,以上就是三种典型总线协议场景设计的核心要点。说白了,AXI 重在乱序和突发,AHB 重在流水线和拆分,APB 重在状态机和等待。每个协议都有它的脾气,摸透了,验证起来就顺手了。
可可精品资料库