1.采样协议的理解
灰色的部分可以当做延迟或者亚稳态理解
协议中的波形图中有的长有的短,这个暂态可能是由于组合电路的延迟,也有可能是时序电路的延迟。
发送激励之前要满足协议,所以要实现AHB协议,lvc_ahb_types和lvc_ahb_transaction在master_driver中实现AHB协议
AHB协议的细致理解
如driver的write动作为例
virtual task do_init_write(REQ t); wait_for_bus_grant(); //第一个周期的上升沿 vif.cb_mst.htrans <= NSEQ; vif.cb_mst.haddr <= t.addr; vif.cb_mst.hburst <= t.burst_type; vif.cb_mst.hsize <= t.burst_size; vif.cb_mst.hwrite <= 1'b1; @(vif.cb_mst); //第一个周期的下降沿 if(t.burst_type == SINGLE) begin _do_drive_idle(); end vif.cb_mst.hwdata <= t.data[0]; // check ready with delay in current cycle forever begin @(negedge vif.hclk); //第二个周期的下降沿 if(vif.hready === 1'b1) begin break; end else @(vif.cb_mst); end // update current trans status t.trans_type = NSEQ; t.current_data_beat_num = 0; // start beat from 0 to make consistence with data array index t.all_beat_response[t.current_data_beat_num] = response_type_enum'(vif.hresp); endtask virtual task wait_for_bus_grant(); @(vif.cb_mst iff vif.cb_mst.hgrant === 1'b1); endtask
如monitor的收集数据为例
//创建对象--记录状态--记录读写数据--在记录数据之前先increase_data内容-- //注意:address只记录头地址,记录一次即可,剩下的地址跟着data记录,data有多少个,地址可以计算出来 //两个周期,NSEQ和IDLE相互交替 //而且时钟块monitor采样,是提前采样 task collect_transfer(output lvc_ahb_transaction t); // collect transfer from interface t = lvc_ahb_transaction::type_id::create("t"); @(vif.cb_mon iff vif.cb_mon.htrans == NSEQ); //第一个NSEQ周期的下降沿提前一点 t.trans_type = trans_type_enum'(vif.cb_mon.htrans); //若是IDLE周期,则跳过等待 t.xact_type = xact_type_enum'(vif.cb_mon.hwrite); t.burst_type = burst_type_enum'(vif.cb_mon.hburst); t.burst_size = burst_size_enum'(vif.cb_mon.hsize); t.addr = vif.cb_mon.haddr; forever begin monitor_valid_data(t); if(t.trans_type == IDLE) //第一个周期和第二个周期之间的线 break; end t.response_type = t.all_beat_response[t.current_data_beat_num]; //当前返回的类型 endtask //这段话和driver的逻辑一样 task monitor_valid_data(lvc_ahb_transaction t); @(vif.cb_mon iff vif.cb_mon.hready); //第一个周期和第二个周期之间的线提前一点 t.increase_data(); t.current_data_beat_num = t.data.size() - 1; //为什么?因为driver的do_init_read中有 t.data = new[t.current_data_beat_num+1](t.data); t.data[t.current_data_beat_num] = t.xact_type == WRITE ? vif.cb_mon.hwdata : vif.cb_mon.hrdata; t.all_beat_response[t.current_data_beat_num] = response_type_enum'(vif.cb_mon.hresp); t.trans_type = trans_type_enum'(vif.cb_mon.htrans); endtask
2.AHB协议信号
理解burst
如果你想要连续发送数据,那么你就会用到burst的这几个比特位。 你的master能发送和slave能接受两种同时满足情况的时候。
目前项目中master中什么能力都没有,优先实现signle的能力。
3.AHB协议中的对齐要求
IHI0011A_AMBA_SPEC---3.10.1中
All transfers must be aligned to the address boundary equal to the size of the transfer. For example, word transfers must be aligned to word address boundaries (that is A[1:0] = 00), halfword transfers must be aligned to halfword address boundaries (that is A[0] = 0).
所有的传输必须对齐地址边界等于传输的大小。
例如,字传输必须与字地址边界对齐(即A[1:0] = 00),半字传输必须与半字地址边界对齐(即A[0] = 0)。
8bits byte字节
16bits 半个字 最低一位为0
32bits 字 低两位为0
16bit(半字) 32’b0000_0000 0000_0000 0000_0000 0000_0000
32bit (字) 32’b0000_0000 0000_0000 0000_0000 0000_0000
4.如何确定系统是小端序还是大端序?
活动字节通道依赖于系统的端序,但AHB不指定所需的端序。
可以用之前的序列来测试,得到以上的图。HADDR=16'h195d,末两位为2'b01即1,且bsize类型是8bit传输,因此有两种情况。
继续观察发现HRDATA=32'hxxxx_02xx, 属于小端序的情况。`因此设计的端序应该是小端序,验证它的数据发送正确对齐应该采用小端序去验证。
5.项目的其他细节理解
5.1 covergroup覆盖组的大致步骤:
1. covergroup--coverpoint 定义、声明
2. 例化覆盖组 new(可能要给参数)
3. sample采样
4. get_coverage() 得到覆盖率 (数值)
covergroup rkv_ahbram_t1_address_cg(bit [31:0] addr_start, bit [31:0] addr_end) with function sample(bit [31:0] addr); ... endgroup
//第一个括号里面的参数是例化new的时候填的参数
//第二个括号里面的参数是采样sample的时候填的参数
5.2 TB文件内做的事情
1.导入testbench所有要用的文件(import、include)
2.接口例化声明
3.module中 例化声明dut、接口
4.initial begin...end中 config机制set配置(接口、单一变量、配置对象)、run_test("")启动测试
5.3 scoreboard和seq中check data之间的区别和联系
在rkv_ahbram_base_virtual_sequence.sv中有compare_data将写和读进来的数据比较,仅仅是数值。
而scoreboard中的比较更加详细,将写和读进来的数据比较,不仅是数值,而且还有当前传输burst的类型、当前传输的大小。
-------------------------------------------------
AHBRAM协议参考文档IHI0011A_AMBA_SPEC
下载地址:
https://files.cnblogs.com/files/blogs/713282/IHI0011A_AMBA_SPEC.zip?t=1685254888&download=true
标签:vif,项目,cb,理解,mon,type,0000,AHBRAM,data From: https://www.cnblogs.com/yphasaki/p/17437947.html