目录
三、UVM通信(component类)
3.1UVM TLM基本概念
3.2TLM通信端口
3.2.1单向通信端口
3.2.2双向通信端口
3.2.3多同名端口通信
3.2.4分析端口——Analysis port(一对多传输、最常用)
3.3TLM FIFO
3.3.1两种TLM FIFO
3.3.2TLM FIFO自带的方法
三、UVM通信(component类)
UVM验证平台的特点是验证环境整体基于面向对象的开发方式,组件之间的通信也是基于TLM通信方式,但在driver与硬件的接口之间,需要将TLM抽象事务降解到基于时钟的信号驱动级别。
3.1UVM TLM基本概念
TLM是一个基于事务(transaction)的通信方式,TLM通信两个对象根据通信动作分为initiator object(通信请求动作发起方)和target object(通信的响应方);根据事务传输方向分为producer(数据产生方)和consumer(数据接收方)。TLM通信端口按照类型可以划分为port(常作为initiator的发起端,凭借port,initiator才可以访问target中实现的TLM通信方法)、export(作为initiator和target中间层次的端口)、imp(只能作为target接收request的末端)。
initiator与target的关系同producer与consumer的关系,不是固定的。但是TLM的通信方法是在target一端中实现,initiator将来作为发起方可调用target内的通信方法,实现数据传输。
TLM通信的步骤可以分解为:
1)分辨出initiator和target,producer和consumer。
2)在target中实现TLM通信方法。
3)在两个对象中创建TLM端口。
4)在更高的层次中将两个对象的端口进行连接。
TLM通信中的三种端口:Port,Export,IMP
1.控制流优先级:Port > Export > IMP
2.Port始终是传输动作的发起者,Export和IMP只能作为动作的接受者。
3.使用connect()建立连接关系时,只有优先级高的才能调用connect()做连接。
4.三种端口使用new()函数在build_phase中创建。(注意:不能用create创建,端口不属于UVM树的一部分)。
5.在有Port,Export,IMP连接的data path中,只能且必须以IMP作为终点。
6.Port,Export相当于一道门,没用存储作用,因而必须以IMP(tlm implement port class)作为终点。
7.IMP在声明时相较于Port/Export多了一个类型参数IMP:
uvm_blocking_put_export#(T)
uvm_blocking_put_imp#(T, IMP);//第一个参数T是这个IMP传输的数据类型。第二个参数IMP为实现该IMP的component类型。
8.发起者的动作实现,最终会落到终点IMP所在的component中,因此必须在IMP所在的component中定义名字为put/get/peek/transport的函数或任务,完成最终的数据传输操作(在blocking的端口,可以将put/get/transport定义为function或task;而noblocking的端口,只允许定义成function)。
3.2TLM通信端口
TLM端口根据是否是阻塞的方式(即可以等待延时)、通信方法和数据流向命名并划分。
3.2.1单向通信端口
单向通信中,port和export端口的参数只有一个;imp端口,参数有两个,第一个是传递的item类,第二个是实现该端口的component。常用传输类型:
单向通信指的是从initiator到target之间的数据流向是单一方向的。单向通信端口是根据阻塞方式、通信方法和数据流向命名并划分。
组合端口 单一端口 方法声明
uvm_put_PORT uvm_blocking_put_PORT
task put(T t)
uvm_nonblocking_put_PORT
function bit try_put(T t)
function bit can_put(T t)
uvm_get_PORT uvm_blocking_get_PORT
task get(output T t)
uvm_nonblocking_get_PORT
function bit try_get(output T t)
function bit can_get( )
uvm_peek_PORT uvm_blocking_peek_PORT task peek(output T t)
uvm_nonblocking_peek_PORT function bit try_peek(output T t)
function bit can_peek( )
uvm_get_peek_PORT
uvm_blocking_get_peek_PORT task get(output T t)
task peek(output T t)
uvm_nonblocking_get_peek_PORT function bit try_get(output T t)
function bit can_get( )
function bit try_peek(output T t)
function bit can_peek( )
表格PORT代表了三种端口名:port、export和imp
注意:阻塞的方法类型为task,这保证了可以实现等待事件和延时;非阻塞的方式类型为function,确保方法调用可以立刻返回。
其中阻塞传输的方法分别包含:
put:initiator通过该方法可以自己生成数据T t,同时将该数据传送至target。
get:initiator通过该方法可以从target获取数据T t,而target中的该数据则应消耗。
peek:initiator通过该方法可以从target获取数据T t,而target中的该数据还应该保留。
非阻塞的方法分别是:try_put、can_put、try_get、can_get、try_peek、can_peek
非阻塞方法的最大区别在于需要立即返回。如果try_xxx函数可以发送或者获取数据,那么函数还应该返回1,如果执行失败则应该返回0。可以通过can_xxx函数先试探target是否可以接收数据,通过返回值,再通过try_xxx函数发送,提高数据发送的成功率。
3.2.2双向通信端口
双向通信指的是从initiator到target之间的数据流向是双向的。双向通信端口也是根据阻塞方式、通信方法和数据流向命名并划分。
transport端口的通信通过transport()方法,相当于一次put传输加一次get传输,可以在同一方法调用过程中完成REQ和RSP的发出和返回;
master和slave的通信方式必须分别通过put、get和peek的调用,通过至少两个方法的调用才可以完成一次握手通信(master端口的slave端口的区别在于:当initiator作为master时,它会发起REQ送至target端,而后再从target端获取RSP;当initiator使用slave端口时,它会先从target端获取REQ,而后,将RSP送至target端)。
3.2.3多同名端口通信
多同名端口通信仍然是两个组件之间的通信,只是为了解决initiator与target之间的相同TLM端口超过一个时的问题(不同的端口组之间要求在imp端口一侧实现专属的方法,即无法在comp2中定义两个同名的put任务)。
UVM通过延伸的端口宏声明方式(`uvm_*_*_imp_decl(SFX))来解决这一问题,而它解决问题的核心在于让不同的端口之间对应着不同名字的任务,这样便不会造成方法名的冲突。
3.2.4分析端口——Analysis port(一对多传输、最常用)
Analysis通信端口特点:
1)analysis_port/export和analysis_imp的通信是一对多的通信,类似广播的形式。
2)analysis端口没有blocking/unblocking的概念,因为他只管广播内容,不管接受的收到与否。
3)只有一个操作:write()函数
4)analysis端口连接也必须以analysis_imp结尾。
同样的在一个component中有多个analysis_imp时,UVM定义了`uvm_analysis_imp_decl(xxx)宏来处理这种复杂情况。
3.3TLM FIFO
TLM FIFO(uvm_tlm_fifo)是一个新的组件,它继承于uvm_component,而且已经预先内置了多个端口及实现了多个对应的方法(无需自己定义write(),put(),get()等函数或方法),只需要用户将端口类型对应即可,TLM FIFO相当于一个缓存两端加上IMP,input和output两端都能连接Port,两侧和它连接的component都能主动发送或索取数据。
3.3.1两种TLM FIFO
uvm_tlm_fifo:包含除analysis端口以外的全部端口,不支持write操作。
uvm_tlm_analysis_fifo:含有下图中的所有端口,支持write操作。
FIFO中端口名字许多带有关键词export,但实际的类型是IMP,UVM掩饰类IMP的存在。
3.3.2TLM FIFO自带的方法
used:查询fifo里存了多少transaction
is_empty: 判断当前fifo是否为空
is_full: 判断当前fifo是否满了
flush:清空fifo中缓存的数据,复位时可以用
TLM FIFO默认的深度是1,如果需要更改,可以在new()是更改参数size的值,如需要无限大小,就将传入的size参数设为0(new函数原型为:function new(string name, uvm_component parent=null, int size=1)。
————————————————
版权声明:本文为优快云博主「Like_ai」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/lizhao_yang_/article/details/121588085