👉关于AHB2APB的设计请看:AHB2APB设计
👉关于AHB2APB的设计的代码请看:AHB2APB同步桥的设计代码
1.项目SPEC
根据ARM官方提供的SPEC,如下:
2.相关协议
中文协议可以看:AHB5协议和APB4协议
ARM英文原版协议:ARM官方文档网址
3.测试点分解
❔分解角度:SPEC文档、AHB协议、APB协议
序号 | 测试项目 | 预期结果 |
---|---|---|
1 | APB协议(APB2 APB3 APB4)中的信号 | |
2 | APB clock频率 <= AHB clock 的频率,频率范围 | |
3 | AHB的不同BURST类型数据的读写访问 | BURST类型和数据位宽的各种排列组合,包括: 8种BURST类型,3种不同的数据位宽 |
4 | 配置参数检查 | 1.不同位宽的地址,0x0000 ~ 0xFFFF每个地址都做读写操作;2.配置REGISTER_WDATA参数;3.配置REGISTER_RDATA参数 |
5 | PCLKEN对HCLK的分频 | |
6 | reset信号 | 在传输过程中发生reset,模块功能能否恢复正常 |
7 | 检查APBACTIVE信号 | 检查APBACTIVE信号的行为是否正确 |
8 | HTRANS | 测busy类型 |
9 | AHB端口信号检查 | 检查HPORT、HREADYOUT、HRESP的功能 |
10 | 多个AHB transfer连续传输检查 | 连续的BURST的访问:1.包括读写;2.不同burst;3.有无IDLE |
11 | APB端口信号检查 | 检查APBACTIVE、PSTRB、PREADY和PSLVERR的功能 |
👊注意:测试点是从多个不同的角度去看的,所有有的可能会重叠,这个都没有什么关系。
4.设计测试用例
1️⃣考虑AHB端,设计sequence:
-
AHB single Write32(从最简单的开始)
-
AHB single Read32
-
AHB Burst 检查
- burst 随机
- size随机
- 数据、地址随机,但是必须要覆盖到边界值
- 读写随机
- HPROT随机
-
将上面的各种sequence进行组合,测试连续间断或不间断的AHB传输
2️⃣考虑APB端,设计sequence:
- pready始终为1
- pready为0,发生有效的位置随机、持续几个周期(1~16)随机
- pslverr始终为0
- pslverr有效,有效的位置随机
3️⃣考虑AHB 、APB时钟频率,设计sequence:
- 频率相同
- 频率比为2:1 、4:1、8:1、16:1
4️⃣组合以上的各种sequence,设计virtual sequence:
- AHB的各种sequence与APB各种sequence运行在不同的AHB、APB时钟频率比下
5.实现难点及处理方法
5.1 在APB的 slave 中:
🎏 driver发送数据和monitor采样的时候,需要判断当前的 reset 信号是否有效 ❓
- 当driver在发送数据时,有可能在这个过程中发生复位。所以在发送数据前要判断复位信号是否有效,或者用fork …join_none也行。
- monitor中采样肯定是forever的。在每次采样前,都判断一下reset信号是不是有效,如果有效的话,那本次就不采样。
🎏 monitor中transaction的例化处理 ❓
- 因为在monitor中声明了一个transaction句柄,如果再采样前就例化了这个transaction,假如这个样采好了,但是没有component及时来拿。下一个时钟沿到来的时候,monitor又采样了,这就把之前的数据给覆盖了。
- 所以为了避免数据包被覆盖,每次monitor采样时,就重新例化一个新的transaction对象。
🎏对于协议中 pslverr 信号的处理 ❓
- 可以把pslverr做到transaction中,通过sequence来随机。
- 也可以把pslverr放到config中,如果要修改pslverr,在发送sequence之前,对apb vip 的config重新配置(可以内置一个reconfig()函数)。
- driver在每次发包的时候,先要等到pready拉高,然后再判断pslverr是否为低。若pslverr为低,则进行后续对总线的读写操作。
🎏 怎么样去反馈在传输时,多个周期的pready信号的拉低 ❓
- 把pready拉低的周期数(pready_num)做到transaction中,通过sequence随机化pready拉低的周期数。
5.2 在AHB的master中:
🎏 AHB的transaction怎么定义 ❓
-
可以将一个burst 划分为一个transaction。用3个动态数组或者队列将 address、data、htrans分别保存,直到将数组或队列中的数据发送完。
-
在transaction类定义时,就需要给address、data、htrans做赋初值和约束。
🎏 AHB是流水线的传输,怎么发包 ❓
AHB在连续传输时,存在地址周期和数据周期交叠的情况。如果使用transaction按一个burst的形式发,可以通过声明两个transaction类的句柄(addr_pkg 和data_pkg)来轮转,解决data_phase和addr_phase 交叠的问题。
-
首先,在时钟上升沿先判断data_pkg是不是空包,如果是null,再判断addr_pkg是不是null,如果是,那就通过try_next_item( ) 获取一个新的burst transaction。
-
当获取到这个addr_pkg时,就把这个data_phase发到总线上(只发送一个address),并且将addr_pkg句柄赋值给data_pkg,也就是addr_pkg 和data_pkg指向同一个transaction对象。此时这一拍时钟沿结束,等待下一拍。
-
当下一拍时钟沿到来时,首先判断data_pkg就不为null了,会将data_pkg中的data数据发送到总线上(只发送一个data)。然后
如果此时data_pkg 和addr_pkg 句柄指向的transaction内还有没发完的data和address,就会继续再往总线上发一个address ,然后又会等到下一拍,将address对应的data发到总线上。 -
由此不断地先发address 再发data循环,直到将transaction中保存address 和data的队列或数组发空为止,结束这个burst,把data_pkg 和addr_pkg 句柄指向null 。再获取一个新的transaction。
🎏 monitor怎么采样 ❓
到底是按一个burst去采,还是按一个single transaction去采样呢?试想一下,monitor采样的数据最终要交给scoreboard ,scoreboard需要比较 apb_monitor和 ahb_monitor 发送过来的数据,而apb_monitor 它发送过来的数据都是一个single transaction。如果我们将ahb_monitor的数据打包成一个burst发过去,monitor内要有打包数据的逻辑,同时发送到scoreboard中,还需要将包拆解成single transaction。所以ahb_monitor可以直接按一个single transaction去采样。
【代码编写中…】