自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(34)
  • 收藏
  • 关注

原创 10.6 config_db

避免第二个参数出错,可以用get_full_name,但是build_phase的时候get_full_name因为树状结构没有完成,所以可以在connect_phase中进行uvm_config_db::set。config_db的参数有两种,一种是结构性的参数,比如driver是否实例化的is_active,可以直接在实例化agent的时候指明其is_active的值。uvm_config_db::get可以在end_of_elaboration中使用。

2025-01-11 17:31:02 204

原创 10.5 聚合参数

验证平台用到的参数有两大类,一类是验证环境和dut都要用到的,通常就是dut的寄存器另一类是环境独有的,比如driver要发送的preamble数量的上下限可以专门写一个my_config extends uvm_object类集中管理。

2025-01-11 16:13:43 156

原创 10.4 DUT参数的随机化

在跨越寄存器的约束的时候,可以建立一个dut_param类,并在其中指定约束,在sequence中将reg_model的指针给dut_param里的寄存器模型,之后调用dut_param里的函数就可以。3 用factory的重载机制,从寄存器中派生一个新的类,在新的类中指定约束,然后重载替换掉原来的寄存器。三种方法:1 assert(p_rm.reg1.randomize() with {reg_data.value == 5'h3})建立dut_param类,里面有update_reg函数。

2025-01-11 15:49:57 198

原创 10.3 sequence的其他问题

心跳的sequence用fork_join_none包起来,因为他是无限循环的,为了防止发送一半objection停止,需要在发送心跳transaction的时候raise_objection,发送结束之后drop_objection。dut需要周期性的心跳信号,两种选择,一种是在sequence中实现,另一种是在driver中实现。driver中实现只需要写一个task,在原有的main_phase中fork_join包起来即可。目的是防止config_db机制第二个参数错误。

2025-01-10 08:57:38 187

原创 10.2 layer sequence

出现这个问题的原因是item_done和try_next_item是在同一个时刻被调用的,导致时间槽的竞争,可以在driver的while中每次等待一个clk。try_next_item是非阻塞的,如果没拿到item我们让driver执行一次drive_idle,在layer_sequence中发现每次发送item都会间隔发送一个drive_idle。p时间槽: driver 进行item_done和try_next_item,my_sqr & ip_sqr转发item_done。

2025-01-09 08:31:00 276

原创 10.1 interface

3 既关心pll之前的频率,也关心pll之后的频率,同时关心过渡期间的频率。第一种:在case中设置周期,在top_tb中拿到周期。此处config_db::get前需要1个单位的时间延迟,不然可能拿不到config_db::set的参数。2 同一个测试用例中频率不同。有两个好处:1 让driver从底层的繁杂数据处理中解脱。测试用例中一般用到三种可变时钟:1 不同测试用例之间频率不同。此外这里的uvm_config_db使用的是非直线的获取。和第一种类似,只是设置两次clk_half_period。

2025-01-07 22:07:59 247

原创 9.4 模块级到芯片级的代码重用

对于寄存器模型的重用:为了重用寄存器模型,不应该在env中例化寄存器模型,而是在base_test中例化寄存器模型,在env中设置一个寄存器模型的指针,在base_test中对他进行赋值。假设dut有ABC三个模块,在模块级验证的时候建立了三套环境envA,envB,envC,在系统级验证的时候可以复用,将envB和envC的driver通过agt中的is_active取消,输入由前一个模块的monitor通过ap发送给后一个模块的model。1 边界输入端的普通sequence。

2025-01-07 08:18:39 301

原创 9.3 参数化的类

定义的时候定义了参数化类,声明的时候不需要参数化(也可以加上),但是实例化的时候必须将省略的参数加上。比如参数化的interface。

2025-01-06 08:45:48 149

原创 9.1 callback机制

新项目要继承老项目,老项目中大量使用了callback机制,可以使用uvm_set_super_type(new_driver,my_driver)来进行替代,这样声明的new_driver就会自动调用之前my_driver的callback。总结:声明A,声明A_pool,在预留callback的函数接口的类中调用uvm_register_cb宏,在预留callback的函数接口类中调用uvm_do_callbacks。3 在my_driver中声明,指明my_driver和A。

2025-01-06 08:30:02 262

原创 8.3常用的重载

比如想发送crc_err的包,可以直接重载driver,在driver中实现crc的错误,在复杂的情况下比较有用。除了driver外,scoreboard等等都可以重载。比如想要创造一个crc异常的case,只需要把transaction用crc_err_transaction重载即可,不需要重新写一个sequence。重载driver使用一些在sequence中难以实现的可以在driver中轻易实现,那么要放弃sequence,都重载driver吗,答案是否定的。和重载transaction类似。

2025-01-02 08:35:31 111

原创 8.2 使用factory机制进行重载

print_override_info:env.o_agt.mon.print_override_info("my_monitor"),其中my_monitor是被重载的类型,这个函数是uvm_component的函数。比如set_inst_override_by_type("env.o_agt.mon",my_monitor:get_type,new_monitor::get_type)print_override_info来输出所有的打印信息,类似的还有debug_create_by_type。

2025-01-02 08:07:39 928

原创 8.1 systemverilog对重载的支持

比如对于transaction,可以直接派生出一个新的类,在新的类中重载约束,新约束即可生效,注意重载约束的名字要相同,否则就是两个不同的约束。即子类对象可以被当做父类对象使用,如果父类的函数声明了virtual,那么子类可以重载这个函数。

2024-12-27 09:02:53 225

原创 7.8寄存器模型的其他常用函数

如果寄存器是32bit但是总线只有16bit,即多地址寄存器的时候,就会最后的for循环来得到要访问的数据,比如多地址寄存器占用'h1005和'h1006,那么target就会拿到这个寄存器,之后通过for循环来确定是'h1005还是'h1006。建立寄存器模型之后,可以通过层次引用的方式访问寄存器,比如rm.invert.read,但是也可以通过地址来访问寄存器模型,即get_reg_by_offset通过寄存器的地址得到一个uvm_reg指针,再调用read,write就可以。

2024-12-27 08:13:59 136

原创 7.7 寄存器模型的高级用法

如果有多个master,那么需要用monitor来采有哪些寄存器操作,这个时候需要用reg_predictor,将reg_predictor和bus_agt的ap口连起来,并设置reg_predictor的adapter和map。寄存器在定义的时候用super.new,第二个参数是系统总线的位宽,默认最大是64,地址位宽默认最大也是64,这两个默认值都是根据宏来定义的,可以重新定义这两个宏。predict--只更新寄存器模型的mirror值,同时不对dut进行操作。predict会更新期望值吗?

2024-12-25 22:23:18 299

原创 7.6 寄存器模型中的一些内建sequence

基于uvm_reg_sequence中定义的一个变量 uvm_reg_block model,在启动的时候需要给model赋值,即把寄存器模型赋值给model。之后在任意sequence中都可以启动这个sequence。如果需要跳过某个寄存器的检查,可以在test的build_phase中进行设置。如果不想检查某个寄存器,可以在test的build_phase中设置为不检查。和检查hdl路径的步骤一致。

2024-12-24 08:55:54 306

原创 7.5寄存器模型对dut的模拟

write、read:无论前门还是后门,写入dut后,寄存器模型都会更新期望值和镜像值。2 通过set函数设置期望值为1,再调用update任务(update会更新镜像值)get可以得到期望值,get_mirrored_value可以得到镜像值。peek、poke:更新期望值和镜像值(poke写,peek读)1 用write,期望值和镜像值都为1。update:更新镜像值和期望值一样。7.5.2常用操作及其对期望值和镜像值的影响。get、set:都是期望值。

2024-12-23 22:33:50 221

原创 7.4复杂的寄存器模型

注意点:configure和add_hdl_path_slice的寄存器起始位置和位宽的顺序不同,比如configure是(0,2),add_hdl_slice_path就是(2,0)如果寄存器存在多个域,那么在这个寄存器本身不进行configure,而是在他所在的uvm_reg_block进行configure,并且通过add_hdl_slice_path来进行区分。从uvm_mem中派生my_memory,在new的时候第一个参数是名字,第二个参数是存储器的深度,第三个参数是存储器的宽度。

2024-12-23 22:03:43 407

原创 7.3后门访问和前门访问

直接赋值 (=):一次性的赋值操作,如果信号有其他驱动,后续会被覆盖Force:持续性的强制赋值,会一直保持该值,即使有其他驱动也不会改变,需要用release解除force。

2024-12-18 08:31:43 302

原创 7.1 寄存器模型简介 7.2 简单的寄存器模型

注意点:此处env.p_rm = this.rm必须在build_phase中而不能在connect_phase中,个人猜测因为rm.build在build_phase中执行,会调用env的的配置,如果此时env.p_rm还未设置,则会导致空指针访问。①首先从uvm_reg中派生一个reg_invert类,在其new函数中有三个参数,分别是name,size,has_coverage,size是寄存器中总共的位数,一般和总线宽度一致。在sequence中,通过sqr的p_rm来访问,不需要用uvm_do。

2024-12-15 19:29:50 609

原创 6.5 virtual sequence的使用

设置default_sequence的时候,可以用uvm_config_db#(uvm_object_wrapper)::set(this,"v_sqr.main_phase",“default_sequence”,case0_sequence::type_id::get())来代替多个uvm_config_db语句。uvm1.1--设置为default_sequence后,sequence的starting_phase就不为null了,但是在uvm1.2中这个设置被取消。

2024-12-14 17:14:32 229

原创 6.7 response的使用

在pre_body()中调用use_response_handler(1),并重写response_handler函数,当use_response_handler(1)的时候会自动调用response_hanlder,不需要显式调用。即在driver中直接赋值,那么sequence中也可以拿到req的变量。复杂的验证平台中,sequence需要得到driver的一个反馈,在sequence中调用get_response(rsp),在driver中调用put_response。

2024-12-14 17:13:40 279

原创 6.6 在sequence中使用config_db

在my_case0中设置参数,设置的路径为 uvm_config_db#(int)::set(this, "env.i_agt.sqr.*,"count",count),在sequence中得到参数,uvm_config_db#(int)::get(null,get_full_name(),"count",count)。路径相同,但是可以sequence给sequence设置参数,即自己给自己设置参数,可以让某段逻辑执行一次。

2024-12-13 09:04:08 257

原创 6.4 sequence进阶应用

sqr对象的创建和句柄的传递:$cast(p_sequcner,m_sequencer),这两个都是句柄,那对象是在哪里创建的呢,是在env中创建的sqr,那seq中是怎么拿到这个对象的呢,是seq.start(p_sequencer)函数的参数是句柄,所以seq才拿到的。seq中的sqr:my_sequnce中自带uvm_sequencer_base的m_sequencer,可以在m_sequencer中启动sequence(比如`uvm_do默认就在m_sequencer中启动);

2024-12-11 23:46:52 591

原创 uvm_do系列宏

目的是只用创建一次对象,但是实现多次的发送,uvm_create_on之后可以进行随机化。- 相当于`uvm_do_on(tr,this.m_sequencer)uvm_do系列封装太多,不灵活,为了增加uvm_do的功能,提供了3个接口。- 相当于tr = new("tr");post_do是finish_item的最后一行。pre_do是start_item的最后一行。mid_do是finish_item的第一行。

2024-12-09 08:53:00 224

原创 sequence的仲裁机制

使用seq.start(env.i_agt.sqr)的时候,需要把seq的starting_phase提前声明,比如seq.starting_phase=phase;sequence中的参数不需要例化,因为是在uvm_sequence_item中就产生好的,比如class sequence0 extends uvm_sequence#(my_transaction);这里的my_transaction不需要例化只需要声明就可以直接使用。

2024-12-08 22:50:14 218

原创 Sequence基础

get_next_item(req)的req是driver的参数,比如那么req就是my_transaction。

2024-12-08 21:34:41 323

原创 UVM验证平台的运行

在base_test的main_phase中设置,phase.phase_done.set_drain_time(this,200),其中phase_done是uvm_phase的一个成员变量。在base_test的build_phase中设置,uvm_top.set_timeout(500us,0),其中第二个参数表示能否被后面的set_timeout语句覆盖。

2024-12-04 21:54:25 233

原创 uvm的TLM1.0通信3

2 在new uvm_tlm_analysis_fifo的时候注意有两个参数,即agt_mdl_fifo = new("agt_mdl_fifo",this);FIFO中的analysis_export和blocking_get_export虽然名字有export,但是都是IMP。

2024-12-04 21:24:39 295

原创 uvm的TLM1.0通信2

杂知识:uvm的pack_bytes存放的时候只能用动态数组存放。

2024-12-02 08:58:18 160

原创 uvm的TLM1.0通信

A:多个信号线级别的信号组合起来;即某一特定功能的信息封装到一起。

2024-11-27 22:05:50 329

原创 uvm_config_db

因为路径设置错误导致无法get到,用此函数可以看到哪些set却没有get,因为set和get一般都在build_phase中,故在connect_phase中使用。有时可以看到第一个参数设置为uvm_root::get,null,uvm_top,都表示uvm树的最顶层。this,"env.i_agt.drv"表示路径,即this.env.i_agt.drv;this,""表示路径,""表示空,则路径为this,即当前组件;"pre_num"为set的第三个参数;"pre_num"表示需要赋值的变量;

2024-11-26 08:45:09 278

原创 uvm打印信息的控制

运行的时候对应component的uvm_warning就会成断点,使用step进行单步调试。设置计数的目标: set_report_max_quit_count(5)在base_test的connect_phase中设置。

2024-11-26 07:58:35 128

原创 uvm的流操作

打印如图,只需要看前面{0,0,87,65,43,21,11,11}部分,pack_bytes的作用即为把transaction中的变量打印。pack_bytes是宏注册之后的功能,需要将transaction通过`uvm_object_utils注册之后使用;pack_bytes可以将transaction中经过注册的变量打包成byte流。tb中随机化my_transaction,使用pack_bytes打包。打包的是transaction中经过注册的。结论:>>可以将数组打包成一个数。

2024-11-25 22:14:32 260 1

原创 【无标题】

碱基识别的几种常见偏差

2022-06-26 16:47:40 1165

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除