文章目录
- 前言
- 一、代码
- 二、错误
- 1.地址范围
- 2. 并行执行线程中变量覆盖的情况
- 3.有关incr的beat
 
前言
- 来源路科验证
- 本节搞定 T3.3AHB总线协议的覆盖:AHB_PROTOCOL_COVER即测试ahb slave接口和master接口支持(尽可能)全部的ahb协议传输场景,主要是支持burst传输 (并行发送)
- 重点在于如何给地址
- 注意该test不是测试映射的完整性的;所以不需要关心整个地址是不是更加完备:即不是把所有的地址都测试完
- 关心的是协议的完整性;只需要保证从三个master到三个slave的访问地址之间没有重合;如果重合会给接下来的数据检查的带来问题;如果同一个地址被两个master的写所覆盖的话;时序上面的延迟会对预测带来障碍
- 可以加一些约束,让波形是自己所期望的;加的约束越少越好,这样的话协议上各种时序出现的可能性更大;前提是设计没问题,要是设计有问题的话,约束一开始不可以放的太开,那么就要从singl-----burst------wrap一步一步来
一、代码
- 思路:先搞定其中的一次并行发送:多个master到多个slave,稳点后,外部套一个repeat,让其多次发送
- 具体代码
--------------------------AHB_PROTOCOL_COVER_seq------------------
virtual task body();super.body();`uvm_info("body", "Entered...", UVM_LOW)cfg.enable_scb = 0;cfg.enable_cov = 0;repeat(loop_count) beginfor(int i=0; i< cfg.mst_num; i++) beginautomatic slv_addr_range_t rng = cfg.addrmap.get_addr_range($random_range(0, cfg.slv_num-1));automatic int mid = i;forkmem_check(mid, rng.addr_start + 'h1000*(mid+cfg.mst_num*$random_range(1, 4)));join_noneendwait fork;    //等第一次传输完以后,在repeat第二次end`uvm_info("body", "Exiting...", UVM_LOW)
endtask
- automatic int mid = i;- mid是在循环体内部使用- automatic关键字声明的变量。这种方式会为每次循环迭代创建一个独立的- mid变量副本。所以每次循环迭代中- mid的值都是动态的,不会相互干扰。
- loop_count别忘记在挂载- sequence之前随机
 - seq中的代码
  
loop_count设置多少以功能覆盖率能不能达到为准
-  如何保证三个 master给同一个slave写的话,地址不重合?
 这里给的地址是rng.addr_start + 'h1000*(mid+cfg.mst_num*$random_range(1, 4),可以看作是基地址+偏移地址,目前的burst_size=32bit,地址需要以4字节为单位进行递增;只要给master一个不一样的地址,后面加4都会不一样,这样就保证了地址的不一样,所以重点在于如何设置偏移地址
-  将一块地址按照 h'1000(32‘h0200_0000---32‘h0200_FFFF)分的话,共15个区间;32‘h0200_0000---32‘h0200_1000是4KB,burst传输要求的地址边界不超过1KB,所以他会完美的去匹配,无论落到哪一个区间,master哪怕是incr他也不会越界,这样就保证了地址的不重合
-  mid+cfg.mst_num*$random_range(1, 4)这块的取值要保证最大值不可以超过14(E)(2+3*4)=14
-  上面的 4的值与mst_num变大和mid都有关
二、错误
1.地址范围
- 出现不应该有的地址范围
  
- 原因:在随机产生数值时,发生了错误,如果随机到5,最大是2+3*5=17>>14,将一块地址按照h'1000(32‘h0200_0000---32‘h0200_FFFF)分的话,最后一个值是E=15`,共15个区间;所以将随机值区间最大改为4
mem_check(mid, rng.addr_start + 'h1000*(mid+cfg.mst_num*$random_range(1, 5)));
2. 并行执行线程中变量覆盖的情况
- 这个错误意味着在并行执行多个序列时,存在某些序列提前完成的情况,导致其他序列的项目无法正常处理。

- 原因:当缺少automatic int mid = i;时,i产生的新的数会将原先的覆盖,导致i只能是3,原先的依次被覆盖掉了;
--------------------------AHB_PROTOCOL_COVER_seq------------------
virtual task body();
super.body();
`uvm_info("body", "Entered...", UVM_LOW)
cfg.enable_scb = 0;
cfg.enable_cov = 0;for(int i=0; i< cfg.mst_num; i++) beginslv_addr_range_t rng = cfg.addrmap.get_addr_range($random_range(0, cfg.slv_num-1));//automatic int mid = i;forkmem_check(mid, rng.addr_start + 'h1000*(mid+cfg.mst_num*$random_range(1, 4)));join_none
end
`uvm_info("body", "Exiting...", UVM_LOW)
endtask
- 解决之道:添加automatic int mid = i;,最好将rng也添加automatic
3.有关incr的beat

- 这里的错误提示数据对比出了问题,到底哪儿出了问题,看的不是很清楚,所以在做有关动态数组对比时,先比较动态数组的size,然后在比较里面的内容,比较每一个数据,
- 详细显示的话,会发现是两边的size不一样
  
  
 定位会发现错误的前面是incr传输,他的地址只要不跨越1KB边界即可,到底传了多少拍,不大清楚;不像incr4之类的,他的拍数是固定的在每一次传输的过程中
  
 可以通过该参数记录,在写数据时记录下来,传递给读数据时的约束
  
 如果给的类型是incr。没有给data.size的话会出问题;incr不限定;;;也就是说如果给的burst_type是incr的话,要限定burst_type的长度
