提纲:
1. 验证平台中都涉及哪些通讯场景
2. SV相关的通讯机制(依据信息载体划分)
(1) 全局变量
(2) TB_TOP内部信号
(3) interface中添加辅助信号(辅助线方法)
(4) Object-handle(OOP)
(5) Event
(6) Mailbox
(7) Semaphore
3. UVM相关的通讯机制
(1) p-sequencer.interface连接sequence和DUT
(2) p-sequencer.get_parent连接sequence和agent
(3) uvm_config_db set和get
(4) TLM连接各个UVM component
4. 题外话
话说通讯无处不在,通讯的机制也五花八门。
鬣狗靠体液气味,乌贼靠身形色彩。灰狼靠仰天长啸,蜜蜂靠曼妙舞姿。
亲人靠鸿雁传书,情侣靠微信视频。领导靠红头文件,村长靠房顶喇叭。
在IC验证平台中,同样也有很多需要通讯的情形。
不必说monitor采集的报文要发给reference model和scoreboard,连接了DUT接口的interface文件要被传送到组件driver和monitor,也不必说driver或reference model的多个独立线程之间需要传递信息,SoC验证平台的C部分和 SV部分需要进行同步,单是sequence一旦需要用到验证平台的configuration文件和DUT接口信号,IC验证者就会有很强烈的在平台组件和sequence之间进行通讯的欲望。
按照实现方式,这些通讯机制可分为两类:SV相关的通讯机制和UVM相关的通讯机制。
SV的通讯机制闵老师备了七种,依次呈现给各位看官。
其一,全局变量之法。
全局是相对局部而言的。
SV(system verilog)的class是一种包含了数据变量和操作处理的基本单元。常言道,九尺之台起于垒土,万丈高楼起于板砖。再复杂的验证平台也是由多个class组建而成。在class内部定义的变量都是局部变量,可以用“this”指示当前操作的class。在class之外定义的变量,称为全局变量。局部变量只在当前class或其子类中直接可见,在实例化该class的上层类中,通过实例化层次关系,间接可见。
除了那些用package打包的class,全局变量对全部的class都直接可见。因此,可以把全局变量作为信息的载体,在验证平台的各个组件之间传递信息,实现通讯。
该方法的优点是操作简单。缺点是全局变量全局可见,出错后不易定位。此外,一旦定义了全局变量,则该变量会在整个仿真生命周期一直存在于服务器的内存之中,不会释放。若是在验证平台中大量使用全局变量,会降低内存的使用效率,进而降低仿真的效率。
其二,TOP_TB内部信号通讯之法。
验证平台的TB_TOP module和其内部实例化的DUT TOP,乃至DUT内部的各个module中的信号,对于uvm_test,env,agents,checker,rm(reference model)等各个组件都是可见的。在验证平台的各个组件之中,可以直接访问TB_TOP和DUT内部的各个信号、变量。
验证者可以在验证平台的TB_TOP中定义中间变量,这些变量可以是reg类型,bit类型,或者wire类型。如图2所示,这些变量作为信息的承载者和传递者,实现各个验证平台组件之间的通讯。例如,在agent_a中,在特定的时机将TB_TOP的bit变量改为1,同时在rm中通过监测TB_TOP的该bit变量是否是1,获取到来自agent_a的该特定的时机讯息。也可以在env中把TB_TOP的reg变量赋为0xFA,在agent_B中可通过访问该reg变量获取该值0xFA,从而实现env到agent_B的通讯。
在SoC验证平台中,C和SV的交互通讯,通常也是通过让C监测一块特定的RAM空间或者某些特定寄存器的值来实现的。SV从后门修改了对应的存储空间的值,C即可获取相应讯息。这与TOP_TB内部信号通讯之法在思路上有相似之处。
此法最大弊端是会降低验证平台的重用性。因为重用时,通常会丢弃被重用验证平台的TB_TOP文件,其中定义的这些中间变量自然也就不能用了。
其三,interface添加辅助信号通讯之法。
通常一个BFM(bus functional model,例如driver和monitor)对应一组DUT的接口。当一个BFM需要用到另一组接口的信号携带的信息时,或者当一个BFM需要监测DUT内部的某个信号的取值时,可以通过在当前BFM的interface文件中添加辅助信号的方法实现。从长远看,此法在BFM的设计之时并不推荐,BFM应与其他DUT端口解耦,BFM应该与DUT内部信号解耦。
一位美女同时只能拥有一个男朋友,但是她可以拥有多个追求者。同理,一个信号在某个时刻只能被一个源头驱动,但是该信号可以在多个地方被监测。具体说来,就是在interface\_1中把interface\_2的部分信号(以及DUT内部信号)也进行定义。接口互联时,把DUT的这部分信号同时连接到interface\_1和interface\_2。在interface\_1中把这些特殊信号定义成input类型。建议只在monitor clocking block中实例化这些信号。在Interface\_1的BFM中就可以直接通过查看接口信号获取到需要的信息了。
当年做几何题时,常常需要在几何图上做辅助线。辅助线做的好不好,直接影响解题效率。在interface中额外加的这些信号就是为开发BFM组件而做的“辅助线”了。
此法要求来自不同interface的信号在同一个时钟域。
此法的优点是简单直观,缺点是接口与DUT连线时要重复连线,略显繁琐。
其四,class指针移形换影之法。
我以为,通讯之最高境界就是移形换影,空间传输。无论是浪漫的土耳其,还是东京和巴黎,都能转瞬即到,想想都令人兴奋。魔兽-冰封王座3中大法师的飞天技能也是被小Y解说认定为最牛逼的英雄技能,没有之一。
在搭建验证平台之时,需要把一些数据在不同的环境组件之间进行传递和共享,例如,要把rm的运算中间数据(array或者queue)传递到checker中,以便与DUT的中间运算数据进行比对。再例如,多个组件之间共用相同的配置信息,验证者希望其中一个组件的配置信息被修改了,其他组件都能同时可见,验证平台能够保证配置信息在各个组件之间的数据一致性。再例如,DUT通过接口访问slave memory模型,验证者希望该模型的数据能被rm可见,rm在产生期望报文时,可以用到跟DUT一样的数据。
这些都可以通过class指针移形换影之法实现。
在验证平台中,先定义一个class,该class可以是一个普通的System Verilog的class,也可以extends from UVM object。然后在该class中定义需要共享的数据结构,例如array或者queue。然后把该class在数据产生的平台组件中进行new()操作,并把数据填充到该class的数据结构中。再在目标组件(需要使用数据的组件)中实例化该class。把该class的句柄指向之前存数据的class,即可实现数据的传递和共享。如图4所示。
其五,event通讯之法。
event是SV定义的一种高效的传递同步信息的方法。通过触发event(-> event)和等待event被触发(@event)的配合,可在验证平台中的不同位置实现处理信息或操作信息的同步。
在组件class内部定义event,可在该组件的各个独立线程(thread)和各个任务(task)之间传递同步信息。在组件class外部定义event,类似全局变量,可在验证平台的各个组件之间传递同步信息。
就像聪明之于人一样,灵活是该方法的优点,过于灵活是该方法的缺点。此法在验证平台中引入的信息同步机制会削弱甚至打乱UVM自带的phase + raise-objection/drop-objection所实现的各个UVM components之间的同步机制,也不利于验证平台仿真挂死后的问题定位。
其六,mailbox通讯之法。
mailbox俗称信箱,可看作是一个管道或FIFO,可在不同线程和不同验证平台组件之间传递信息。信息的类型可以是bit,int,string和class指针。
mailbox我用的少,也见得少。在验证平台组件之间传递报文信息,通常用TLM机制。而简单的控制信息若用mailbox,总觉得有些大材小用了。或许这就是mailbox最尴尬的地方了。
其七,旗语通讯之法。
绿皮书上讲解旗语semaphore时,打了一个比方,把旗语比作夫妻共用的一辆车,当丈夫开的时候,妻子就没得开。丈夫开完后妻子才能开。同样,妻子开走了,丈夫要用车也只能等。从通讯角度看,通过这辆车,可以传递出夫妻二人谁在外出工作谁在家中休息的信息。
在搭建验证平台时,若需要对同一个资源进行竞争和仲裁时,可使用旗语。
以上是SV的七种通讯方式。关于UVM的通讯方式也略备几种,不成敬意,请各位看官笑纳。
第一种,p\_sequencer。
通常情况,uvm\_component被认为是组成uvm验证平台的框架实体,而uvm\_objects是附着在uvm\_component之上的数据集合。在uvm\_component中可见uvm\_object,但是在uvm\_object中不可见uvm\_component。sequencer源自 uvm\_component,env源自uvm\_component。sequence是源自 uvm\_object。验证者在写sequence时,有时候需要在sequence中“可看到”sequencer,env,和DUT的接口信号。
例如,在sequence中用uvm\_do\_on执行sequence时需要指示具体的sequencer。
例如,在sequence中需要使用env的configure文件的变量。
例如,在sequence中需要监测DUT的某个信号。
解决办法是首先在sequence中获取sequencer的指针,然后以sequencer为桥梁,得到env的的指针和virtual interface的对象。再通过virtual interface,从sequence对DUT接口信号的监测。
万事开头难,最难的有人已然帮我们做好了。为了从sequence中获取sequencer的指针,UVM专门定义了一个宏。如图5所示。
其中m\_sequencer是指向sequencer基类的指针。通过$cast将该指针指向验证平台定义的virtual sequencer。还顺便给验证平台的virtual sequencer统一起了一个名字:p\_sequencer。
通过p\_sequencer,在sequence是可直接访问virtual sequencer内部实例化的各个sub-sequencer。
可是如何通过p\_sequencer获取到env的指针呢?莫慌,且听闵老师慢慢道来。
从uvm_component的create函数可知,当创建一个uvm_component时,需要把该component的上一级层次的文件的指针作为parent参数,传入create函数。如下图所示。此处的parent通常是用”this”指示。virtual sequencer就是通过这种方式将实例化它的env的指针传入到其内部的parent变量。
在sequence中通过p_sequencer.get_parent()可获取验证平台的env组件的指针。一旦有了env组件的指针,env中例化的各个验证平台组件就都对sequence可见了。
我初见此法是在2013年的深圳坂田,那个来自新德里的小伙安东尼曾对我说,可以在svt_pcie_sequence中通过p_sequencer.get_parent可得到svt_pcie_env的指针,我半信半疑。再见此法已是在2021年的cherry IC验证公众号了。
既然可以通过p_sequencer获取env指针,那么也可以通过p_sequencer获取virtual interface的指针。可先在sim_top定义virtual interface,把需要监测的DUT信号与virtual interface的信号连接上,再通过config_db set/get将virtual interface传输到virtual sequencer中。
如此这般,便可在sequence中通过p_sequencer.virtual_interface.signal监测DUT的信号了。
p_sequencer的操作流程可由图7概况。
第二种,uvm_config_db set/get。
uvm提供了一种直通的方式,在各uvm component组成的实体框架组件之间进行传递信息。被传递的可以是变量,class的指针,interface文件等。平台各组件通过factory注册之后,路径和位置就固定了。config_db set/get能够直通传讯,也正是基于此。
set和get成对使用,需要保证通讯时,set和get的变量类型相同。时间上先set,后get。值得注意的是,config_db_set/get不能理解为一个队列或FIFO的push/pop操作。Set之后,传递的信息不会被一次get而清除或释放,而是会被UVM保存起来,每次的get操作,都可以获取之前set的信息。
第三种,TLM。
TLM是transaction级别的通讯行为,主要是报文信息的传递,而此处报文信息是在时序信号上进行抽象出来的信息。在验证平台的monitor、reference model和checker之间,传递transaction通常是用TLM机制。
各位看官,今天备的就这些了。
种SV的通讯机制各有所长,灵活运用,相互配合,互相补充,再加上UVM的几种通讯方式,就能大幅提升验证平台各个组件的通讯和交互的效率。遥想当年,蛇蝎二妖为祸人间,一位白发老人在一只穿山甲的帮助下,种出了七个不同颜色的葫芦。葫芦成熟后,变成了七个各怀绝技的葫芦娃。葫芦七兄弟相互配合,同心协力,加上降妖宝物的加持,最终打败了蛇蝎二妖。这七个葫芦就好比这七种通讯机制,而UVM的几种通讯方法就好比那黄天化手中的千年避邪宝剑和万魔洞中的照妖镜。验证者若能灵活运用,一定能事半功倍,马到功成。
题外话
春节去亲戚的亲戚家吊唁,仪式颇有不同。孝子贤孙跪于灵前,按辈分逐一起身三拜九扣,撒酒祭奠。门外鼓乐齐鸣,其声呜呜然,如怨如慕如泣如诉。我于人群中观看,不禁悲从衷来,泪水簌簌而下。此处位于蒲城北郊,距大孔三十里路。
入职新公司,偶遇行同学。一日说的话竟比高三一年的还多。衣不如新,人不如故。但愿无论出走多远,归来仍是少年。
原文: IC验证者之家
作者: 一只特立独行的猪
相关文章推荐
- UVM中add_typewide_sequence和add_sequence的区别
- 灵动微课堂 |开源项目:基于MM32F0160微控制器的机械键盘
- 从FPGA说起的深度学习(七)-循环并行化
- 从FPGA说起的深度学习(六)-任务并行性
- 双MIPI摄像头图像系统设计
- 世界上最伟大的开源作品-基于FPGA的开源摄影机--Axiom Camera
更多FPGA干货请关注IC设计技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。