uvm实战-学习笔记_第1页
uvm实战-学习笔记_第2页
uvm实战-学习笔记_第3页
uvm实战-学习笔记_第4页
uvm实战-学习笔记_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

?UVM实战(卷1)?学习笔记

看了第1/2/3/4/5/6/8/9.1这几个章节.

第一章是综述,第二章是一个具体的例子,学习笔记从第三章相关内容开始.

我个人觉得UVM重要的局部〔特点的局部):

1)factory机制(overrideconfig_db)

2)TLM传递

3)phase机制

4)sequence-sequencer以及virtualseq/sqr

内容中的截图根本来自于UVM源代码、书自带的例子和?uvml.l应用指南及源代码分析?

这个PDF里的.需要结合书(?UVM实战1卷1)?第1版)来看这个笔记.

第3章UVM根底

3.1uvm_component和uvm_object

常用的类名字:

这个图是从作者张强的?uvml.l应用指南及源代码分析?里截得,不如书上3.1.1里的图好.

uvm_sequencer也是代码里必须有的,所以我加了uvm_sequencer

uvm_void是---■个空的虚类.在src/base/uvm_misc.svh中定义:

virtualc1assuvnri_\/oidendclass

红框的是我们搭testbench的时候用的比拟多的基类.

常用的uvm_object派生类:

sequencer给driver的transaction要派生自uvm_sequence_item,不要派生自

uvm_transaction

所有的sequence要派生自uvm_sequence或者uvm_sequence的派生类,可以理解为

sequence是sequencejtem的组合〔集合).driver向sequencer索要item,sequencer检查

是否有sequence要发送item,当发现有item待发送时,就把这个item发给driver.

常用的uvm_component派生类:

所有的driver要派生自uvm_driver.driver用来把sequencejtem中的信息驱动到

DUT端口上,从transaction-level|R]signal-level的转换.uvm_driver需要参数(REQRSP),比

uvm_component增加了几个成员.重要的是seqJtem_port和req/rsp.

(src/comps/uvm_driver.svh)

uvm_seq_item_pull_portGeq_item_port

uvrn_seq_iten_pull_por_tseq_item_pr□d_iP//alias

/〃/Port:rcp_port

//ThioportprovidocQCaLtornatoscyoTcondingrcsponsoGbacktotho

〃originatingsequencer.Whichporttousedependsonwhichexportthe

//GoqucncorprovidesForconnoction.

uvm_analysis_partrsp_port

req

rsp

monitor/scoreboard派生自uvm_monitor和uvm_scoreboard,但是

uvm_monitor和

uvm_scoreboard并没有在uvm_component根底上做扩展.src/comps/uvm_monitor.svh

virtu.alclassuvrn_munLtorextendsuyn_cornponent

〃Function*new

Z/Cr&atcsand白门instanceG-Fthioclassusingthenormal

^7/conetructorargumentsFor<uvjn_coinponent>:isthenainQofthe

7/ins-tanc@,andAparantAisthshandletothehierarchicalparent,ifany«

Functiannew.stringname,uyn_camponentparent):

eu.per.new(name3papent

endPuinctLon

izonutstaticstringtype_nani9

x/ir-UINI-Puinctionstringget_type_name(J;

retj.rnt.yp&_name:

endPuinctLon

endclass

sequencer要派生自uvm_sequencer.sequencer做了很多扩展,但是如果我们自己写的

sequencer里没有增加成员的话,可以直接写如下代码:

typedefuvm_sequencer#(传递的sequencejtem类名)sequencer类名;

由于sequencer在agent中例化,所以一般写在agent类文件里.

reference_model派生自uvm_component.

agent要派生自uvm_agent.uvm_agent里多了一个is_active的成员.一般根据这个active

来决定是否实例化driver和sequencer.is_active变量的数值需要在env的build_phase里设

置完成〔可以直接设置,也可以用uvm_config_db#(int)::set).

env要派生自uvm_env.uvm_env没有对uvm_component扩展.

src/comps/uvm_env.svh

virtLiaIcIa:=1:=1u'i/rii_envextendsuvm_Dorriponent;

Function:new

〃Createsandinitializesaninstanceo-Fthisclassusingtherwrmal_______________

7/constructorarguments-Por<uviiii_coijipm«t.>;Aname-Isthe:name&F工he

//instancefand'"p白rent"isthehandletothehiersrcfiicalparent,i?any*

Tuncti□nnci-.i(stringname-"U-'—u.vni_coriiponentparent-null:

super.newnamesparent.

endFLKCtion

conEtstatic'=:t-ingtype_name

1rtu.si4'Lnnstvingget_type_n.ariie

「EtLT/ntype_nanie

end户unction

endcIase

所有的test都要派生自uvm_test或者它的派生类.uvm_test也没扩展

src/comps/uvm_test.svh

■/irtualclascu.vrn_testextendsULVTii_Cnmponent

//Function;new

x/

〃Createsandinitializesaninstanceofthisclassusingthenormal__________

^J/constructorargtimentsFor<uwiKii_compor>en3±J§Jhenameofthe

A

//instance,白rtd""pareniU™isthehandletoth@hirardnlcalparent,i-Pany

Lonnewi'=:tringn.amejuvni_conponentparent

super.neujtnamenparentj

end-TunctiDri

conststaticstringtype_name=!

virtualfunctionstringget_type_nsme

retLi.rntype_name

end-Punction

endulast:

uvm_object和uvm_component的macro

macro非常重要,事关把这些类的对象注册到factory机制中去.

uvm_objectmacro

1)对于uvm_sequencejtem就统一用(假设不用parameter):

'uvm_object_utils_begin(item类名)....field_automation...

'uvmobjectutilsend

2)对于uvm_sequence,要加上

'uvm_object_utils(sequence类名)

可能还需要'uvm_declare_p_sequencer(sequencer类名)的声明

uvm_componentmacro对于drivermonitorreference_modelscoreboardsequencercaseagent

envuvm_component派生类都要加上:

'uvm_component_utils(类名)

uvm_component里的成员也可以像uvm_object里成员一样,用field_automation机制.

'\TVULcomp.二七二二mbeci_r:,{mydiivei}

"JLvnLJiel(prrUVM_ALL_OM}

'avnL_caiiLpoE.ent-_.;tiL3_end

field_automation机制:

对于uvm_object派生类来说,field_automation机制让对象自动有的copycompareprintpack

unpack等函数,简化了实现uvm_component派生类里一些function/task的工作量

对于uvm_component派生类来说,field_automation机制最重要的是可以在build_phase中

自动获取uvm_config_db#()::set()的数值(必须加super.build_phase(phase))--也就是不用写

uvm_config_db#()::get()

注意:field_automation的macro的类型要和uvm_config_db的参数类型一1致:

如下例如代码,fieldjntvsuvm_config_db#(bit[47:0])这个时候super.build_phase()是不起作

用的.

|classmy_sequencerextendsuvm-sequencermy_transactionbitdmac

bitsmac

//intdmac;

//intsmac;

'uvmcomponent.LJitils_beginmy_sequencer)

'uvm_-Field_intdmac

、uvm_-FieldJnt(smac

'uvm_component._uitils_end

Q-iL.Luniumy_c3eeCbuild_phastuvffl_phasephase

■■=urjir,juilcLphaetahase

uvn_config_dbtjji:setJi-u=:

想要起作用的话,需要用

Furct1onnidmy_caseObuild_phaseu.vm.phasE-phase)

ou.pn-r-bnild_phasephase

//uv™_conFig.cJb#(bit[47:0]1:isetCthiSi"env.i-agt*3qrM3"dmac'B,48'WF9765);

/HLIVUI.config_<Jbt(bit[47:0]):aienv.i-agt*3qrw3fismacb,4sh89F23);____

uvm.config_db#Cintsettthis3

int:=5

clone=new+copy源代码中可以看到clone函数一上来会做一次create,然后调copy函数

src/base/uvm_object.svh

[functionuun_abjcctuvin_otijtctuJcirwuvm_nb.jrcttrip:tmpthis.crwrt!?

tnpnull______________________________________________

Mii^h-repcrrt-Marninselw

tffi口copythis

reiiirntnp

sfidfLinctlan

""capij

//

dcuGDpjrhs:

deptn.

if:deptJite'In

UyE_alQb=ll_C"y」Vlap_C]AT「

d-TuHOtlan

3.2UVM的树形结构

置N-1完整的UVM树

uvm_component的new/create要注意第一个参数是名字,第二个参数是parent指针.

UVM真正的树根是“uvm_top".根据上面这个树结构,可以看出一个个component的

parent是什么.uvm_top的parent是null.当一个component在实例化的时候,如果

parent参数设成null,那么parent参数会被仿真器自动设置成uvm_root的实例uvm_top.

在6.6.1章节里也提到了,sequence在uvm_config_db#()::get()的时候,第一个

参数设成“null〃,实际就是uvm_root::get()3.5.1章节也提到了这个

层次结构函数:

get_parent()get_child(stringname)这两个分别获取parent指针和指定名字的child指针.

get_children(refuvm_componentchildren*])获取所有的child指针

get_num_children()获取child个数

get_first_child(refstringname)get_next_child(refstringname)获取child的名字(反映至U

stringname上),返回值是0/1两种情况

应用参考代码如下(改动的2.5.2例子中的my_agent.sv):

〔functionvoidny_aEontconnnc:t_phjEciuvn_phjEBiphasiDijivm-componentchildren3

uum-componentchild

stringchild_narie

supsr.cnnnoEt_pha=c-1ph,

if(is.active.beein

dru5eq_itpmj)ortconnectsqr5&q_itpri-i_eApc!r-t;endap=fton.ap:

.thiEg.Qt_-Ru.ll_namc-thi-=.301

.parent,this.ffet_num_children());

thigget-chi1dren〔children:

■Poreach1childrenibegin

一"^hle.ger_Fu1L_n力uE1,1,ct-i11dHen'1]geLrariP^^hi兄ren[1].get_-FuIl_n.3ne(

ond

childjMeeVchild

ifchilOnull.begin

ifthia-set.First_child1child_namebeEin

-sjthisget-PulLnarie.chilcLrar"5,

92^1j.rhls.eet_ru:Ll_nam&!).chiId-naneund

ond

i?13Fbeein

注意:上述代码是在connet_phase中实现的.

上述代码的打印结果如下:

my_agent'snameisuvm_test_top.env,i_agt,parent'sfullpathisuvm_test_top.env,childrennum

is3

uvm_test_top.env.i_agtOchild:drv->fullpath:uvm_test_top.env.i_agt.drv

uvm_test_top.env,i_agtlchild:mon->fullpath:uvm_test_top.env,i_agt.mon

uvm_test_top.env.i_agt2child:sqr->fullpath:uvm_test_top.env.i_agt.sqr

Thisshouldbei_agt.my_agent'snameisuvm_test_top.env.i_agt

uvm_test_top.env.i_agtfirstchildnameisdrv

uvm_test_top.env.i_agtnextchildnameismon

uvm_test_top.env,i_agtnextchildnameissqr

my_agent'snameisuvm_test_top.env.o_agt,parent'sfullpathisuvm_test_top.env,children

numisl

uvm_test_top.env.o_agtOchild:mon->fullpath:uvm_test_top.env.o_agt.mon

UVM_WARNING/tools/synopsys/vcs/G-2021.09/etc/uvm/src/base/uvm_component.svh(1846)

@0:uvm_test_top.env.o_agt[NOCHILD]Componentwithname'drv'isnotachildofcomponent

,uvm_test_top.env.o_agt,

Thisshouldbeo_agt.my_agent'snameisuvm_test_top.env.o_agtuvm_test_top.env.o_agtfirst

childnameismon

3.3fieldautomation机制

注意数组类型的fieldmacro比一般的要少real和event的macro.一般的对于enum类型有

3个参数,而数组的只有2个参数.联合数组的macro比拟多

常用函数需要注意packunpackpack_bytesunpack_bytespackjntsunpackjnts返回值都是

bit个数.

field-automation标t己位

17bit中bit03copybitl3no_copybit23comparebit33no_comparebit4——printbit53no_print

bit63recordbit73no_recordbit8——packbit93no_pack

UVM_ALL_ON是zb000000101010101

UVM_ALL_ON|UVM_NO_PACK这样就会忽略掉packbit

field-automation的macro可以和if结合起来,参考3.3.4的代码

'uvm_object_utils_begin(my_transaction)

'uvm_field_int(dmac,UVM_ALL_ON)

'uvm_field_int(smac,UVM_ALL_ON)if(is_vlan)begin

'uvm_field_int(vlan_infol,UVM_ALL_ON)

'uvm_field_int(vlan_info2,UVM_ALL_ON)

'uvm_fieldjnt(vlan_info3,UVM_ALL_ON)

'uvm_fielcljnt(vlanjnfo4,UVM_ALL_ON)end

'uvm_field_int(ether_type,UVM_ALL_ON)

'uvm_field_array_int(pload,UVM_ALL_ON)

'uvm_fieldjnt(crc,UVM_ALL_ON|UVM_NOPACK)

'uvm_field_int(is_vlan,UVM_ALL_ON|UVM_NOPACK)'uvm_object_utils_end

这个is_vlan变量可以在sequence里约束成0或1,来实现vlan或非vlan

ps:我觉得这个地方代码其实写成像3.3.3里的有一个crc_error的randbit的更合理一些.

然后crjerror是UVM_ALL_ON|UVM_NOPACK,Wcrc是UVM_ALL_ON

3.4UVM打印信息限制

get_report_verbosity_level()

set_report_verbosity_level(UVM_HIGH)只对当前调用的component起作用

set_report_verbosity_level_hier(UVM_HIGH)对当前及下面所有的component起作用simv

+UVM_VERBOSITY=UVM_HIGH命令行方式---我觉得用这个就可以了

重载打印信息:

set_report_severity_override(UVM_WARNING,UVM_ERROR);

上述函数都是在connect_phase及后面的phase使用

设置UVM_ERROR到达一定数量结束仿真

set_report_max_quit_count(int)设成0就是无论多少error都不退出

get_report_max_quit_count()返回如果是0,说明无论多少error都不退出

设置在main_phase前调用.

simv+UVM_MAX_QUIT_COUNT=10

3.4.43.4.53.4.63.4.7我觉得应该用不大至I」,就不做笔记了

3.5config_db机制

uvm_config_db#(类型)::set/get(component指针,“变量名字",para4)

都是4个参数:

第一个参数是一个component指针,如果是null的话,相当于uvm_root::get()

第二个参数是个路径字符串,第一和第二两个参数组和成一个完整的路径

第三个参数对于set、get要完全一致,是变量名字

set的para4是数值,get的para4是变量

component中的成员变量如果:

1)component用uvm_component_utils宏注册

2)变量用field-automation宏注册

3)component的build_phase函数里有super.build_phase(phase)

那么可以省略get语句

跨层次多重set的时候,看set的第一个参数,层级越高,优先级越高.

调用set的时候,第一个参数尽量使用this

同层次设置的时候是时间优先

非直线设置的时候注意第一和第二参数的使用,如果需要parent指针,那么要用

this.m_parent

config_db机制支持通配符,但是作者不推荐使用通配符.但是在对sequence的成员set的时

候需要用通配符(6.6.1章节).

使用如下函数调试config_db

check_config_usage()print_config(l/0)这两个函数在connect_phase函数中调

simv+UVM_CONFIG_DB_TRACE

注意:第二个参数设置错误不会报错!!---config_db机制务必要注意参数的书写.

第4章UVM中的TLM1.0通信

TLM是TransactionLevelModeling缩写

这章要搞清楚portexportimpfifo以及几种操作function/task和对应component中要实现的

function/task

下面的箭头方向都是限制流的方向,不是数据流方向.

我觉得作为一个VMM用户会觉得TLM有点难理解,总想用VMM_CHANNEL去套,结果把自

己搞晕.像port等其实是调imp所在component的task/function.

我看UVM源代码里有一个uvm_seq_item_pull_port的class,它的基类是uvm_port_base.在

uvm_driver的成员seq_item_port就是这个类型的.与它对应的是uvm_seq_item_puIl_imp,

uvm_sequencer的成员seq_item_export就是这种类型.在my_agent.sv中会connect它们.

Ifunationvoidmy__agent:::coimect:_phase(uvm_phasephase):

super,connect;phase{phase1;

Hif(isactive=UVM_ACTIVE)begin

drv.seqItemport.connect(sqr.seqitemexport]1;

_-,-,_________-」一―一________________

-end-----------------

ap=mon.ap:

endfunation

4.2端口互连

port是动作的发起者,export是动作接收者,但是需要以一个imp来结束.

可以port3export3impport3port3imp也可以portfimpexportfimp

port-mp用的较多,portfportfimp可以用port指针赋值来实现portfport[4.3.2章节)

操作:

putget/peektransport,transport相当于一次put+一次get

peek和get的不同(4.3.4章节):使用uvm_tlm_analysis_fifo的时候,get任务会使fifo中少

一个transaction;而peek任务是fifo把transaction复制一份发出,内部缓存中的transaction

不会减少.--一般情况下peek完以后,还得调get.

上述操作都有阻塞和非阻塞之分.portexportimp的类型也有blocking和nonblocking之分.

port/export/imp类型:put/get/peek/get_peek/transportblocking/nonblocking/不区分blocking­

nonblocking之分

imp要多一个参数,除了声明transaction类型(或者REQRSP类型)以外,还要声明实现这个

接口的component

connect的一定是同类型的port/export/imp

TLM的关键在于“与imp对应的component中task/function的实现”.

假设A_port.connect(BJmp),那么需要实现的task/function为:

A_portBJmpTask/functionFunction

uvm_blocking_put_portuvm_blocking_put_impput

nonblocking_putnonblocking_put_imptry_putcan_put

putputputtry_putcan_put

blocking_transportblocking_transporttransport

nonblocking_transportnonblocking_transportnb_transport

transporttransporttransportnb_transport

get_peekget_peekgetpeektry_getcan_get

try_peekcan_peek

get/peek/get_peek和put类似,上述task或function必须要实现,如果用不到就写个空函

数(章节4.2.9).

注意上述task或者function的参数.put是一个transaction参数,get/peek是output的

transaction参数,transport是————个req参数——个output的rsq参数.

连接用connect函数实现,从名字就可以看出来,这个必须在connect_phase中调.

4.3通信方式

这节应该是本章重点.实际使用中用analysis_port3analysis_imp还是

port3tlm_analysis_fifo(port可以根据实际情况自己决定.

analysis_port(analysis_export)可以连接多个imp(一对多的通信)(3put和get系列端

口与相应imp的通信通常是一对一的(可以一对多,但是本书没有给出一对多的例子4.2.1章

节有介绍)•analysis_port(analysis_export)更像是一个播送

analysis_port(analysis_export)没有阻塞和非阻塞的概念.它是一个播送,不等与它相连

的其他端口的响应.

analysis_port(analysis_export)必须连的imp是analysisjmp.analysisjmp所在的

component必须定义个write的function注意:是function

代码例如:4.3,1例如代码的analysis_port文件夹

classbc-tondsuvm_canpon&ntrlassac>-tcHdfiU'?rccenpanont

uv»i_ar»»lij5i5_irF?"U-trans^ctionBB_inpuvn—emalijs15_por-tniy_trar»5airtion

functimnewstringnoneuv»x_conpanentparentfunctio»ineu•"string,naneuvm_conponer>tparent

super.nenameparentsuper.nei.।nan^parent

end-Purctianendfunctian

funcTlonvoidbulId-phaseuvwuphase*te^nfuncrJonvoidbu11cLt^iaseavrut^^sepl"u=r=€-

externfunction••■Qidconnect-phaseuvn_pha-ephaee--ter-nvirtualt-?1-r»ain_pi-^5esephnse

■、functionvoidwriteray_transactiontrEmcfc1035

externvirtualtasknain_phasephase

cndclass■I'urct-ianabuild_phas&u'vTrt_phaa&pKasc

■upar-bulld_phas0.piafie

•>oBbu11d-phaseuv(i_phaeephase►•_ap广堂,this

supert«jild_phaeephaseerctfuncrlon

B_inpneuthis

endruncticntHkfinain_phaseuwi_phasephase

ny_trarr5aetinntr:

Function-.oidBtxrr)oct_phA»uvn_ph^»phaa。repeatbegin

dupe>isonnect-phasephase

EMunciIoritr-neu

asserttrrandc«nize

function>cidBwrite.ny_transactiDntrfi_apwritetr

anti--___一

tt".printondtack

endfunctlor*

taskBm»in_phaseuvni_pha5e曲ose

endtask

componentC和B的代码基本一致。env的connect_phase函数里做connect:

■Functionvoidmy_envconnect_phaseuvm_phasephase

superconnect_phasephase

A_instA_apconnectB_instB_imp

A_instA_apconnect1C_instC_imp

end-Function

component中有多个imp的时候,如何实现write函数?

4.3.2给的例子中,scoreboard有两个imp,分别从output_agent和reference-model的

analysis_port获取transaction,然后做compare.这个时候需要用:

'uvm_analysisjmp_decl(—标记)这个macro,然后“Write"函数变成"\/7示0_标记()〃

函数,analysis_port所在component不用变,还是调write。函数即可.代码例如如下:

使用macro声明

-:las:z;mu-seareboarde>tendF;uyscorebcard;

nig_transactione?;pect._qiiEue[$]:

uvanalysie_imp„rn口nitori*(rny_transaction,my_scoreboardmDnitor'_LrnpLLvri_analyEi£Jmp_modeL4(my_t

ransaction,my_scnr-eboardmodeljnip

"u.viriponent._utiIsmy_scareboand)

I函数变名字

write

|BTiinrtioni/oidmy_ecor'&boar'd:zurite_niQd&limy.transactiontrexpect_qdeue.push_bai_[==(tr

endPij.ncTion

■Pu.iictIon./Didmy_5coreboard;;i.'4rite_rnonitormy_transactiontr):rriy_traneactiontrrip_tran;

^Hbitresult;

^Mif:2eKpect_qu.eu.e-size()>cbegin

tmp_tranGi-ipect-queue.pap_4'pont(

tr

analysis_port所在component实现不变.

taskmy_nnonit.or'nain_phaseuvn-phasephaseH

my_transactiont.rl

endtaskrlwritetrH

while[1)beginH

“吐1e(.1)beginp口rt.get(.tr.neui_tr—neu("neui_trcopyitr):_______________________

en_d__._____________________________________________________________neui_trprint();

taskn与yu_p^neinrHdmelatt:nrm_apihna_snpeheatwspEhaLsHLevm_phasephase

Imy_tr-3nscaocltlieonctr_;one_pkttrH

Imy__tr.3nsactionn曰LU_trj________________________________________________________

endtask

使用uvm_analysis_fifo(uvm_tlm_analysis_fifo),analysis_fifo的本质是一一块缓存+两个

imp.用fifo来实现portffifoGport

使用fifo最重要的是选好两端的port类型,然后根据选好的两端port类型,来选择fifo上

要连接的imp/exportfifo本身实现了write。put()get()peek。等一系列的function/task,在两

端port所在的component中直接调就可以.

连接在fifo两端的都是port,所以connect函数的起点是两端.

4.3.3的例如代码:

可以看到env里声明的几个fifo都是connect_phase函数中connect函数括号里的参数.

i_agt.ap>o_agt.ap和mdl.ap是analysis_port

mdl.port、scb.exp_port和scb.act_port者6是blocking_get_port

mij-agenti_agt;my_agento_agt;my_rriQd&lmdlrnL|_ecQr'ebQardscb

A

u.vnvt1rn_analysis_-F1-TD『「归transactionagc1T口u.vn-i_t1n_analysis_-PiDrny_transactiun3gt_mdl_Fi4'u

u.vt]rn_analysis_-PiF□irny_t.ransmctinn.)mdL_scb_fi4'n

4'u.nct.ionnDN(.st-ingname3uym_componentpar9n£si£pcr-neN(nameparent

end-Punction

irtua1function^Idbu.Lld_phasejJA.TTi_phasephase)

^■Fupei--bu.iIcLphase(.phase

^HuEigtrriy_agent.typejd:create("i_a2:311,this

^■o^gtriLLagenttypejd:;create(3this:;i_agt,is_active

s_active

^■md1^niu_rriodel:t.LjFje_Ldcreate(Isthit;J:

^Hsebniy-scoreboapd::t!jpe_id:createthis);

^Hagt-si::b-Fi-Fo=new(this);

^|agt_mdl_Fi-Fo=newC'>力,thj:=;);

^■mdl_ecb_Fi-FQ=nQid('riri1_:r-n_f?.--'.this);___________________________________________________

end-Fumotion

externirtualFurction..■□iciconnect_phasephasephase)

u.ym_component_u.tile(rny_eny.endcLasc

PJ.ncticn7ziidrny_envconnectsphase1u.vni_phasephasE-):

:z:j£.perconnect_phasephase.):

i_agt.-apconnect(agt_mdl_Fi-F'u.analysis_expurt

nd1port-connect(agt_mdl_Fif'ublocking_get._export)

mdlapcanned1md1_scb_-f'LFaanalysis_p:=<pijrt

scbnexp_portconnect(.md1_scb_fif'oblocking_get_BKpijrt)

□_agt-apcannect(.agt_scb_fif,anaLysio_export

sebnact_port-cnn0已匚tf5匚b_Fi卡口blocking_get_export

ion

fifo上有很多export,但是这些export实际都是impsrc/tlml/uvm_tlrn_fifo_base.svh

//Thefo-llowingsraalliestothesboveput_export+u.vn_put_inip(T.thi.G_type-bLocking.pu.t„exportuvruputjmpN(T.

this_typenonblockingj)ut_&xport;

〃『h和FoHaulingarealls1iasedtotheabovegeit_peek._esepiort、,uihichprovicfeB//thegupM言r&etafi卜电白白interracc、’

u.vm_gRt_peek_Lnn|:T|thi.G_typebLocking_get_expDrt;riDnb1□

iivrru-gBCpeekZinT.this_tL|pe(Tcking_get_Bxpbrt;

get.export:

u.vrn_gEt_peek_in(TthiG_type,C

-bLocking_peek_eMpDrt;

LivrrugBt_peek_inthis_tL|pe(Tnonblneking_peek_export;

u.vrri_gGt-_peek”inthLG_typGpeek_export;

u.vrri.g□t_p@ek_in0^thi.G_typ(T

Li.vrLget-peek-impnonb1Dckingget.peek.expor

上面连接的agtmdlfifo.analysisexport也是一个analysisimp:源代码中实现如下:

src/tlml/uvmtlmfifos.svh

|uvmanalysisimp#(T,uvmtlmanalysisfifo#⑴)analysisexport;

fifo是一个component,可以调一些函数来debug:

used()is_empty()is_full()flush()

fifo里缓存深度可以在new的时候用第三个参数设置.

问题:fifo的两端是不是一般就是analysis_port和blocking_get_port?----感觉4.3.5

章节开始一段文字描述是这个意思.

使用fifo还是imp自己来把握.各有各的好处.

imp可以使用uvm_analysis_imp_decl(_标记)的macro,有时候会很方便.

而analysis_fifo可以用for循环来操作fifo数组,也可以带来代码的简洁.imp不能在

connect和new的时候用for循环.

第5章UVM验证平台的运行

5.1phase机制

所有的phase如下列图:

build_phase

cn[i_Of_elaborajt}oni_pliasc

团口rt_O匚!dmulationjli.asc

pre_rcse!t_jph3ir

prc_CDntii?iiTC_phaHC

cnintljurejhHse

post_confiinire_ph3se

Fdj]J)0]且完

r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论