#记录S家AXI VIP使用时遇到的一些常见bug及其解决方案;
#记录S家AXI VIP一些常见问题和解决方案;
#不定时更新
一、Fatal
二、Error
2.1 AXI_SLV agent的axi_port_kind被错误设置成非AXI_SLAVE类型
error_log:axi_port_kind must be set as AXI_SLAVE for slave agent AXI_MASTER
solution:修改svt_axi_port_configuration中的axi_port_king
this.axi_s_port_cfg = axi_port_cfg::type_id::create("axi_s_port_cfg",this);
this.axi_s_port_cfg.axi_port_kind = svt_axi_port_configuration::AXI_SLAVE;
2.2 atomicity地址对齐检查错误
error_log:Monitor Check that a transaction never has an atomicity gurantee greater than that the alignment of its start address on ARADDR/AWADDR., Reference: AMBA AXI and ACE Protocol Specification: ARM IHI 0022E ID022613; Section A7.1 - current addr = 'hc87a4622, expected aligned addr = 'hc87a4620, atomicity size = 'd8 bytes.
solution1:svt_axi_configuration中的atomicity_size,用于检查原子操作的对齐地址是否正确,不care此协议属性的话,可直接将svt_axi_configuration中的atomicity_size赋值为-1,禁用检查。
solution2:care此协议属性的话,transaction做好atomic trans的地址约束。
2.3 一笔burst地址超4K边界错误
error_log:Monitor Check that a write burst cannot cross a 4K boundary! - addr = 'he5284f6f. burst_length = 'd16. burst_size = BURST_SIZE_128BIT.
solution1:如果slave大小超过4K,那就约束地址,使一笔burst中不会跨越诸如:32'h0000_1000, 32'h0000_2000, ...之类的4K边界地址,把跨4K边界的trans拆成多包来发。
solution2:如果需要强行构造这种异常激励,并希望环境不会报错,只能把port_cfg中的protocol_checks_enable关闭,但这样也会导致其他协议相关的检查被关闭,因此只建议一些特殊的定向case这样做。
2.4 master发出的AXI_ID位宽与slave返回的AXI_ID不匹配
error_log:Saw bvalid assertion for id 'h53. But, no corresponding transaction found.
solution1: 如果是slave返回确实有问题,debug RTL。
solution2:master发包有问题,axi_trans.id_width与port_cfg中设置的id_width不匹配导致,往往还会伴随类似以下的warning信息:Invalid id of 0x266 provided, must be <= 0xff base on port_cfg.id_width('d8).如果是这种,约束transaction,使AXI_ID位宽在允许范围内。
三、Warning
3.1 transaction产生的wvalid_delay[]动态数组size与burst_length不匹配
error_log:reporter [is_valid] Invalid wvalid_delay.size() of xxx provided, must be === xxx based on burst_length(‘d15).
solution:产生wvalid_delay[]时,new的size = burst_length。
`uvm_create(axi_trans)
axi_trans.port_cfg = cfg;
axi_trans.id = $urandom_range('h0,'hffff);
axi_trans.xact_type = svt_axi_transaction::WRITE;
axi_trans.addr = 64'h0000_0000_0001_0000 | ('h0000_0000_0001_0000 << i);
axi_trans.burst_type = svt_axi_transaction::INCR;
axi_trans.burst_size = svt_axi_transaction::BURST_SIZE_128BIT;
axi_trans.atomic_type = svt_axi_transaction::NORMAL;
axi_trans.burst_length = $urandom_range(5,16);
axi_trans.data = new[axi_trans.burst_length];
axi_trans.wstrb = new[axi_trans.burst_length];
axi_trans.data_user = new[axi_trans.burst_length];
axi_trans.wvalid_delay = new[axi_trans.burst_length];
`uvm_send(axi_trans)
3.2 axi_master(slave)_vif重复set
err_log: The slave virtual interface is valid in the recieved configuration object, and a virtual interface has been recieved through the config db. Replacing the slave vif in the configuration object with the vif recieved from the config db.
solution:vif只set到env这一层,在env中通过调用port_configure.set_master_if/set_slave_if函数传递vif即可,这种方式在多slave、多master场景中更加适用。
3.3 读传输rresp[]/rready[]动态数组size与burst_len[]数组大小不一致
err_log: Invalid combination for Read/Coherent Read, xact_type(READ) or coherent_xact_type(READNOSNOOP), rresp size('d0), and burst_length('d9). For a Read/Coherent Read the rresp size must be the same as the burst_length.
solution: 读传输master transaction在instance burst_length[]时,instance同样大小的rresp[]。
3.4 窄带传输时size-wstrb-wdata-wysiwyg_enable不匹配
err_log: Invalid wstrb['d1] based on port_cfg.wysiwyg_enable('b1), starting addr('h10), burst_size(BURST_SIZE_128BIT) and burst_type(INCR). Valid byte lanes are 'd32 to 'd47 (lane numbering starts from 0), but wstrb is asserted for invalid byte lanes too.
solution1: 如果不采用wysiwyg模式(what you see is what you get),则在给wstrb-wdata这2个信号赋值时,必需采用靠右对齐的方式。
example1: wdata物理位宽为1024bit,size = 128bit,addr = 0x10,wysiwyg_enable = 0,length = 9, burst_type = INCR; 按常理,wstrb[0] = 'hfffe0000、wstrb[1] = 'h0000ffff_00000000、wstrb = 'hffff0000_00000000 ......但实际上应右对齐,即wstrb[0] = 'hfffe、wstrb[1] = 'hffff、wstrb[1] = 'hffff,VIP会自动映射为正确的wstb。
如下:
`uvm_create(axi_trans)
axi_trans.port_cfg = this.cfg;
axi_trans.addr = 'd16;
axi_trans.burst_type = svt_axi_transaction::INCR;
axi_trnas.burst_size = svt_axi_transaction::BURST_SIZE_128BIT;
axi_trans.burst_length = 9
axi_trans.data = new[axi_trans.burst_length];
axi_trans.wstrb = new[axi_trans.burst_length];
for(int i=0;i<axi_trans.burst_length;i++)begin
if(i == 0)begin
axi_trans.wstrb[i] = 'hfffe;
end else begin
axi_trans.wstrb[i] = 'hffff;
end
axi_trans.data[i] = 'h11111111_11111111_11111111_11111111 * (i+1);
end
`uvm_send(axi_trans)
可以发出如下的写数据:
读出数据:
四、常见问题
4.1 mornitor TLM port的使用
svt_aci_port_monitor提供了多种TLM接口,包括如下五种:
1. item_start_port:该TLM只提供第一笔初始trans,对于axi写trans,该TLM提供包含(写指令aw),(写数据w)相关的全部信息,但不会返回(resp channel)信息,对于axi读trans,该TLM只提供(读指令ar)信息,建议使用该port口作为参考模型的输入数据;
2.item_observed_port:该TLM提供一笔被mornitor检测到的有效axi_trans的所有信息,建议将此TLM口接收的数据作为实际数据;
3.snoop_item_started_port:暂未使用过;
4.snoop_item_observed_port:暂未使用过;
5.tlm_generic_payload_observed_port:暂未使用过;
4.2 axi_m_seq的非阻塞性
axi_m_seq所产生的axi_transaction激励会以非阻塞的方式传递给sqr->drv,因此seq的body函数结束的时间不等于drv驱动完成的时间,或者monitor检测到激励完成的时间;在如下所示代码段中,Enter 和Exit之间消耗的仿真时间只取决于ax指令发完的时间,不取决于trans resp的时间;
task axi_m_base_seq::body();
axi_m_pkt axi_trans;
`uvm_info("body", "Enter axi_master_base_seq", UVM_HIGH);
fork
forever begin
get_response(rsp);
end
join_none
for(int i=0;i<10;i++)begin
`uvm_create(axi_trans)
axi_trans.port_cfg = this.cfg;
assert(axi_trans.randomize());
`uvm_send(axi_trans)
end
`uvm_info("body", "Exit axi_master_base_seq", UVM_HIGH);
因此想要获得trans结束的准确时间点,需要配合event握手机制实现;
或者修改代码,在seq中采用sv的process方法,即可兼容interleave传输、outstanding传输、并将axi_master_seq修改为阻塞性,即所有axi激励完成b ch和r ch的握手后,seq才结束,代码如下:
task axi_m_base_seq::body();
axi_m_pkt axi_trans;
process p ;
int trans_num = 10;
`uvm_info("body", "Enter axi_master_base_seq", UVM_HIGH);
fork
begin
p = process::self();
for(int i=0;i<trans_num;i++) begin
get_response(rsp);
end
end
join_none
for(int i=0;i<10;i++)begin
`uvm_create(axi_trans)
axi_trans.port_cfg = this.cfg;
assert(axi_trans.randomize());
`uvm_send(axi_trans)
end
p.await();
`uvm_info("body", "Exit axi_master_base_seq", UVM_HIGH);
endtask:body
4.3 mornitor event的使用
svt_aci_port_monitor提供了多种uvm_event可以用于握手同步,具体有如下:
1.EVENT_TX_WRITE_XACT_STARTED:
该event会在monitor在接口上观测到new write transaction时触发;
2.EVENT_TX_READ_XACT_STARTED:
该event会在monitor在接口上观测到new read transaction时触发;
3.EVENT_TX_XACT_ENDED:
该event会在monitor在接口上观测到transaction结束时触发,对于写trans,即所有trans的b resp返回时触发,对于读trans,即所有的读数据被成功接收时触发;该event比较实用,应用于seq中可同步axi trans结束时刻;