寄存器模型
寄存器是模块之间相互交谈的窗口,可以通过读取寄存器的状态获取硬件得当前状况,在验证过程中 ,对寄存器进行验证也是必需的,为了保证硬件与硬件之间正确的交谈。
寄存器模型的基本概念
uvm_reg_field:这是寄存器模型中的最小单位。
寄存器的硬件实现是通过触发器,而每一个比特位的触发器都对应着寄存器的功能播描述,一个寄存器一般由32个比特位构成,将单个寄存器拆分之后,又可以分为多个域(field)y不同的域往往代表着某一项独立的功能。 单个的域可能由多个比特位构成,也可能由单一比特位构成这取决于该域的功能模式可配置的数量
不同的域就对于外部来说,大致可以分为WO、RO、RW等等操作
上图中的寄存器有多个域,每个域的属性也可以不相同,reserved域表示的是该域所包含的比特位时保留以作日后功能的扩展使用,而对保留域的读写不起任何作用。
简单的寄存器模型
简单的DUT模型
1、首先需要一个从uvm_reg派生一个invert类 ,作用是:在new函数中,要将invert寄存器的宽度作为参数传递给super.new函数。这里的宽度并不是指这个寄存器的有效宽度,而是指
2、派生自uvm_reg的类都有一个build,这个build与uvm_component的build_phase并不一样,它不会自动执行,而需要手工调用
3、实例化后,要调用data.configure函数来配置这个字段。configure的第一个参数就是此域(uvm_reg_field)的父辈,第二个参数是此域的宽度,第三个参数是此域的最低位在整个寄存器中的位置,第四个参数表示此字段的存取方式,第五个参数表示是否是易失的(volatile),这个参数一般不会使用,第六个参数表示此域上电复位后的默认值,第七个参数表示此域是否有复位(默认写1),第八个参数表示这个域是否可以随机化,第九个参数表示这个域是否可以单独存取。
4、定义好寄存器以后,需要在reg_block派生的类中将其实例化,图中代码下半段。
5、一个uvm_reg_block中一定要对应一个uvm_reg_map,系统已经有一个声明好的default_map,只需要在build中将其实例化,这个实例化的过程并不是直接调用uvm_reg_map的new函数,而是通过调用uvm_reg_block的create_map来实现
6、最后一步则是将此寄存器加入default_map中。uvm_reg_map的作用是存储所有寄存器的地址,因此必须将实例化的寄存器加入default_map中,否则无法进行前门访问操作。
寄存器建模的基本要点和顺序
将寄存器模型集成到验证平台中去
最终寄存器模型的前门访问操作最终都将由uvm_reg_map完成
验证平台中使用寄存器模型
寄存器前门访问
以write为例:
1、当调用寄存器的write()任务后,产生uvm_reg_item类型的transaction:rw,之后调用uvm_reg::do_write()
2、在uvm_reg_map中,调用reg_adapter.reg2bus将rw转换成bus driver对应的transaction。
3、把transaction交给sequencer,最终由bus driver驱动到对应的bus interface上。
4、bus monitor在bus interface上检测到bus transaction 。
5、reg_predictor会调用reg_adapter.bus2reg将该bus transaction转换成uvm_reg_item。
6、从driver中返回的req会转换成uvm_reg_item类型,如防止sequencer的response队列溢出,需要在adapter中设置provides_reponses.
7、寄存器模型根据返回的uvm_reg_item来更新寄存器的value,m_mirrored和m_desired三个值
寄存器后门访问
指的是利用UVM DPl(uvm_hdL_read、 uvm_hd_deposit),将寄存器的操作直接作用到DUT内的寄存器变量, 而不通过物理总线访问,从广义上来说,所有不通过DUT的总线而对DUT内部的寄存器或者存储器进行存取的操作都是后门访问操作
寄存器模型的常规方法
我们在应用寄存器模型的时候,除了利用它的寄存器信息,也会利用它来跟踪寄存器的值。 寄存器模型中的每一个寄存器,都应该有两个值,一个是镜像值 (mirrored value)y一个是期望值(desired value)。期望值是先利用寄存器模型修改软件对象值,而后利用该值更新硬件值; 镜像值是表示当前硬件的已知状态值。 镜像值往往由模型预测给出,即在前门访问时通过观察总线或者在后门访问时通过自动预测等方式来给出镜像值。
自动预测
没有在环境中集成独立的predictor,而是利用寄存器的才做来自动的记录每次寄存器的值,并在后台自动调用predict()的方法称为自动预测。
这种方式简单有效,然而需要注意,如果出现了其它一些 Sequemce直接在总线层面上对寄存器进行操作(跳过寄存器级别的write()/read()操作,或者通过其它总线来访问寄存器等这些 额外的情况,都无法自动得到寄存器的镜像值和预期值
显示预测
显示预测是一种更为可靠的预测方法,在物理总线上通过监视器来捕捉总线事务,并将捕捉到的事务传递给挖补例化的predictor,该predictor由UVM参数化 类uvm_reg_predictor例化并集成在顶层环境中。
在集成的过程中需要将adapter与map的句柄也一并传递给predictor ,同时将monitor采集的事务通过analysis_port接入到predictor一侧。 这种集成关系可以使得monitor一旦捕捉到有效事务,会发送给 predictor,再由其用adapter的桥接方法。实现事务信息转换,并将转化后的寄存器模型有关信息更新到map中。 默认情况下,系统将采用显式预测的方式,这就要求集成到环境中的 线UVC mnitor需要具备捕捉事务的功能和对应的analysis port,以便于同predictor连接。
应用场景
寄存器模型不但可以用来检查硬件寄存器,还可以配合scoreboard来实时检查DUT的功能。
寄存器检查
检查DUT
覆盖率自动收集
参考:UVM学习笔记--寄存器模型 Register Model_wonder_coole的博客-CSDN博客_@register_model