《uvm实战》学习笔记

《UVM实战》学习笔记

一、factory机制

  1. 在uvm平台中,一个利用`uvm_component_utils注册的类,只要被实例化了,就会自动调用它的main_phase。Run_test(“class name”)会根据类名创建一个实例,如果这个类利用工厂机制注册了,则它的main_phase会被自动调用。

二、objection机制

  1. 在每个phase中,uvm会检查是否有objection被提起,如果有,则等待这个objection被撤销之后停止仿真;如果没有则马上结束当前phase。
  2. raise_objection语句必须在main_phase中第一个消耗仿真时间的语句之前,否则没有作用。
  3. 注意仿真时间和运行时间的区别。

三、interface

  1. 应该尽量杜绝在验证平台中使用绝对路径,避免使用绝对路径的第一个方法是使用宏,第二是使用interface。
  2. 在类中不可以声明interface,只可以声明virtual interface。
  3. 如何把top_tb中的interface和cdriver中vif连接起来,使用config_db机制,分为set和get。
  4. Set的第二个参数是寄信的目的地在uvm树形结构中的路径。
  5. 通常是driver以及i_mon以及o_mon需要接口,而且driver和i_mon共用一个接口。

四、build_phase

  1. 在uvm启动之后,build_phase会自动执行,在build中主要是通过config_db机制来传递一些数据,以及实例化一些成员变量等。
  2. build_phase是function,main_phase是task phase。
  3. `uvm_fatal 宏在调用之后,会调用$finish来自动结束仿真。
  4. `uvm_fatal之后两个参数,uvm_info有三个参数,冗余度对于fatal来说没有意义。
  5. 无论传递给run_test的参数是什么,它创建的实例名字都是uvm_test_top。
  6. Config_db使用双冒号是因为这两个函数是静态函数。

五、transaction

  1. 通过transaction实现由信号级到事务级的转换。
  2. uvm_component_utils注册的变量具有静态声明周期,比如driver。而由uvm_object_utils注册的变量具有动态生命周期,比如transaction。
  3. 在调用transaction的randomize被调用之后,post_randomize会被自动调用。

六、uvm树形结构

  1. uvm具有树形结构,树的根节点就是由run_test创建的uvm_test_top。
  2. Build_phase自上而下的运行,即从树根到树叶,直到把所有的build_phase都执行完毕,才开始执行后面的其他phase。

七、monitor

  1. monitor负责将端口级别的信号转化为transaction级别。
  2. Byte pyload[]是动态数组,需要new[psize]来实例化,注意不是new(), byte data_q[$]是队列,不需要new()。
  3. i_mon的必要性:一是driver和monitor由不同的人员来实现,可以避免对协议理解的偏差;二是可以提高代码重用性。
  4. 验证组件的创建 一般都是在build_phase中完成,也可以在new中完成。

八、TLM

  1. 在uvm中,通常用tlm来实现component之间transaction级别的通信。
  2. 发送数据可以用uvm_analysis_port接口,接受数据可以用uvm_blocking_get_port接口,中间用uvm_tlm_analysis_fifo进行连接和缓冲。
  3. 接口之间的连接在env中的connect_phase中进行。
  4. ap在i_mon中例化,这个ap要传递到env中的话,需要在i_agt中创建一个ap,但是这个ap不需要例化。

九、task和function

十、phase机制

  1. Connect_phase在build_phase执行完成之后执行,但是build是自上而下执行,connect_phase是自下往上执行。
  2. Report_phase在main_phase执行之后执行。
    十一、field_automation机制
  3. 使用uvm_object_utils_begin 和uvm_object_uitls_end来实现transaction的factory注册。在定义transaction时利用field_automation机制注册之后就可以直接使用compare、copy、print等函数。
  4. 使用filed_automation机制的另一个好处是简化了driver和monitor。可以使用pack_byte和unpack_byte实现字节流的打包和解包。
  5. Unpack_byte将字节流还原成transaction中的字段,还原的顺序取决于uvm_field注册时的顺序,它的输入参数必须是一个动态数组。
  6. 动态数组在使用之前必须使用new[]来指定数组大小。

十二、sequence机制

  1. sequence不属于验证平台的任何一部分,sequencer通常在i_agt中例化。sequence属于object类,而sequencer属于compnent类。
  2. sequence就像是一个弹夹,里面的子弹是transaction,而sequencer是一把枪,将transaction发送给driver。
  3. 每一个sequence都有一个body任务,当一个sequence启动之后,会自动执行body中的代码。
  4. `uvm_do是一个常见的宏,它用于:a. 例化一个transaction;b. 将其随机化 ; c. 将其发送给sequencer。也可以用start_item和finish_item来产生transaction。
  5. 一个sequence在向sequencer发送transaction之前,会先发起一个请求,sequencer会将这个请求放到一个仲裁队列里面。作为sequencer,它会做两件事,一个是检测仲裁队列是否有请求;第二是检测driver是否申请transaction。
  6. driver如何向sequencer申请transaction?
    在uvm_driver中有seq_item_port,在sequencer中有seq_item_export,在i_agent中的build_phase中将它们连接起来,从而建立一个通道。当二者连接之后,就可以在driver中通过seq_item_port.get_next_item(req)来向sequencer来申请transaction,在完成驱动之后,会通过seq_item_port.item_done()来通知sequencer以及sequence,接到通知后,sequencer会将备份的transaction丢弃,sequence则是会返回当前的uvm_do,然后启动下一次uvm_do宏来产生下一个transaction。
  7. uvm_driver中有成员变量req,它的类型就是传递给uvm_driver的类型,比如transaction,所以这个变量可以直接使用。
  8. driver中只负责驱动transaction,不负责产生,只有有transaction就会驱动给dut,因此需要做成无限循环的形式,monitor以及ref_model、scoreboard也是类似的。
  9. sequence如何将transaction传递给sequencer呢?
    只需要在定义sequence之后,在某个组件中通过seq.start(i_agt.sqr)启动sequence即可,它的参数就是要发送transaction的sequencer。
  10. 在uvm中, objection一般伴随着sequence,通常只在sequence出现的地方才会提前以及撤销objection。sequence是弹夹,当子弹打光了之后,便结束仿真。
  11. Try_next_item和get_next_item,前者是非阻塞的,后者是阻塞的。Try-next_item更加接近真实的driver情况。
  12. 启动sequence的另一种方式是default_sequence,通过config_db set机制来使用default_sequence,并且不需要使用get。
  13. 可以在不同的地方通过default_sequence来启动sequence,比如在env中,第一个参数是this,第二个是相对于第一个参数的相对路径,路径需要指定到phase一级,比如main_phase,第三个和第四个参数纯属规定,照抄就行。
  14. 在使用default_sequecne之后又如何提起以及撤销objection?
    在sequence中有一个变量starting_phase,可以通过这个变量在sequence中提起以及撤销objection。

十三、config_db机制

  1. 到目前为止,在三个地方使用到了config_db机制,第一是在top_tb中通过config_db来传递virtual interface;第二个是传递变量,如agent中的UVM_ACTIVE和UVM_PASSIVE;第三是使用default_sequence,从而将sequence和对应的sequencer联系起来。
  2. 关于第二个传递变量uvm_active,如果所有的例化均在build_phase中完成,则不需要config_db来传递,可以直接赋值,推荐这种方式。
  3. 在top_tb中使用config_db机制来设置vif的时候,由于top_tb一个类,没办法使用this指针,因此第一个参数使用null,第二个参数使用绝对路径uvm_test_top.xxx。

十四、加入base_test

  1. 在uvm中,通常根节点是一个派生自uvm_test的类。
  2. 当存在多个case时,可以在命令行中使用+UVM_TESTNAME=casen,来指定运行的case。

十五、寄存器模型

  1. 寄存器模型的本质就是重新定义了验证平台和dut之间的寄存器接口 。
  2. 前门访问和后门访问,前者通过发起总线操作完成,消耗仿真时间,后者通过层次化的引用来访问,不消耗仿真时间。
  3. uvm_field、uvm_reg、uvm_reg_block
  4. Uvm_reg_map,在每个uvm_reg_block中至少有一个uvm_reg_map,它存储寄存器的偏移地址,并负责在前门访问的时候将将偏移地址转换为物理地址。

其他

  1. 一般来说,class文件后缀用.svh,package文件和interface文件后缀用sv。
  2. 对于在tb中使用`include 进行包含的文件,需要在filelist文件中使用+incdir+PATH来说明查找的路径,因为默认的查找路径为当前路径。对于import的文件,比如uvm_pkg.sv,在filelist中添加路径即可。
  3. cshell中设置局部变量和环境变量分别使用set和setenv,在bash中使用export来定义环境变量,局部变量则可以使用=号直接定义并初始化。
  4. Set、setenv和export三者之间的关系:set 和 setenv最大的却别就是set设置的变量只对当前进程有效,不能传递给子进程。bash中export也类似。
  5. 环境变量在source之后,原来已经打开的目录中不会生效,需要重新打开这个目录才会生效。
  • 2
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值