仿真文件
仿真文件可以分为3类,在不同路径下,分别是VIP通用文件、AXI VIP文件和example文件,首先建议将example拷贝到VIPCAT的路径之外。
/usr/Cadence/vipcat/vipcat_11_30_106/tools/denali_64bit/ddvapi/sv /usr/Cadence/vipcat/vipcat_11_30_106/tools/denali_64bit/ddvapi/sv/uvm/cdn_axi /usr/Cadence/vipcat/vipcat_11_30_106/tools/denali_64bit/ddvapi/sv/uvm/cdn_axi/examples/legacy_examples/using_soma_interface/axi4验证环境
tb
主要是定义了时钟、复位,系统包含1主、1从、1无效主、1无效从,对4个子接口又包了1层总接口,但实际接口均为example文件定义,接口包含获取路径的方法。
string instance_path = $sformatf("%m"); function automatic string getPath(); return instance_path; endfunctiontop_test
example路径下的vip_example.f会指定测试用例,也可以直接通过生成路径下csh脚本修改。
test首先会例化sve,这是个example文件,就是把env和sqrt包在了一起。
axi4UvmUserSve axiSve0;test在build phase对VIP进行了配置,VIP以agent形式例化,*后是4个agent的名字,然后通过agent的inst成员进行配置。
uvm_config_db#(int)::set(this,"*activeMaster.inst", "waveformDebuggerMonEnable", 1); uvm_config_db#(int)::set(this,"*passiveMaster.inst", "waveformDebuggerMonEnable", 1); uvm_config_db#(int)::set(this,"*passiveSlave.inst", "waveformDebuggerMonEnable", 1); uvm_config_db#(int)::set(this,"*activeSlave.inst", "waveformDebuggerMonEnable", 1);test还在build phase传递了sequence。
uvm_config_db#(uvm_object_wrapper)::set(this, "axiSve0.axiEnv0.activeMaster.sequencer.run_phase", "default_sequence",userSimpleSeq::type_id::get());env
由于VIP是agent,environment同样是example文件。
env首先例化了4个agent,例化的agent是VIP agent(cdnAxiUvmAgent)的example定义的子类。
axi4UvmUserActiveMasterAgent activeMaster; axi4UvmUserActiveSlaveAgent activeSlave; axi4UvmUserPassiveAgent passiveSlave; axi4UvmUserPassiveAgent passiveMaster;env在build phase对VIP进行了配置,通过cfg类实现。
activeMasterCfg.is_active = UVM_ACTIVE; activeMasterCfg.PortType = CDN_AXI_CFG_MASTER; uvm_config_object::set(this,"activeSlave","cfg",activeSlaveCfg);agent
example文件定义了VIP agent的2级子类,只做了传递接口1件事。传递方法是tb传递虚接口,子类agent通过虚接口的getPath()获取路径字符串,然后通过配置agent的字符串变量实现驱动/检测接口的绑定。
uvm_config_db#(...)::get(this,"","vif",vif); __internal_interface_Path = string'(vif.getPath());seqr
sequencer为example文件,包含了主/从agent的seqr。
cdnAxiUvmSequencer masterSeqr; cdnAxiUvmSequencer slaveSeqr;seq
示例使用sequence为userSimpleSeq,为example文件,从前面可以看到发给了master agent的seqr。seq内容是发送4次长burst传输和8次随机传输,通过约束trans进行传输。
denaliCdn_axiTransaction trans; `uvm_do_with(trans, { trans.Type inside {DENALI_CDN_AXI_TR_Read, DENALI_CDN_AXI_TR_Write}; trans.Length > 16; }); get_response(trans);VIP
agent
Cadence AXI VIP以agent的形式展现,对于多主多从场景需要例化多个agent。类名为cdnAxiUvmAgent,包含常规的monitor、driver和sequencer(题外话,VIP竟然都是明码)。
需要注意的是agent不包含虚接口,是通过__internal__interfacePath字符串变量实现传递。
cdnAxiUvmMonitor monitor; cdnAxiUvmDriver driver; cdnAxiUvmSequencer sequencer; cdnAxiUvmInstance inst; cdnAxiUvmMemInstance regInst; cdnAxiUvmMemInstance memoryInst; string __internal__interfacePath; cdnAxiUvmConfig cfg;trans
VIP中传输类的类名为denaliCdn_axiTransaction。
首先包含协议信息,例如AXI3/4、AXI/ACE、AXI/AXI-Lite。
rand denaliCdn_axiSpecVersionT SpecVer ; rand denaliCdn_axiSpecSubtypeT SpecSubtype ; rand denaliCdn_axiSpecInterfaceT SpecInterface ;然后包含传输信息,包括读/写、地址、数据、边带信号。
rand denaliCdn_axiDirectionT Direction ; rand reg [63:0] StartAddress ; rand reg [7:0] Data [] ; rand reg [7:0] Alen ; rand denaliCdn_axiTransferSizeT Size ; rand denaliCdn_axiBurstKindT Kind ; rand reg [4:0] Region ; rand reg [31:0] Auser [] ; rand reg [31:0] Buser [] ;同时包含一些接口信息,和延时等控制信息。
// id max size rand reg [31:0] ArIdLength; // address max size rand reg [31:0] ArAddrLength; rand reg [31:0] UserData ; rand reg [31:0] BreadyDelay ;