tlm是transaction level modeling(事务级建模)的缩写。简单来说,一个transaction就是把具有某一特定功能的一组信息封装在一起而成为的一个类。
如何要在两个uvm_component之间通信,例如实现monitor和scoreboard通信,最简单的方法就是使用全局变量,在monitor里对此全局变量进行赋值,在scoreboard里监测此全局变量值的改变。
这种方法简单、直接,不过要避免使用全局变量,滥用全局变量只会造成灾难性的后果。
由config机制的特性可以想出另一种方法来,即从uvm_object派生出一个参数类config_object,在此类中有monitor要传给scoreboard的变量。在base_test中,实例化这个config_object,并将其指针通过config_db#(config_object)::set传递给scoreboard和monitor。
当monitor要和scoreboard通信时,只要把此config_object中相应变量的值改变即可。scoreboard中则监测变量值的改变,监测到之后做相应动作。但是一是要引入一个专门的config_object类,二是一定要有base_test这个第三方的参与。永远不能保证某一个从base_test派生而来的类会不会改变这个config_object类中某些变量的值。
tlm通信中有如下几个常用的术语:
1)put操作,通信的发起者a把一个transaction发送给b。。a具有的端口(用方框表示)称为port,而b的端口(用圆圈表示)称为export。这个过程中,数据流是从a流向b的。
2)get操作,a向b索取一个transaction。a上的端口依然是port,而b上的端口依然是export。这个过程中,数据流是从b流向a的。到这里,读者应该意识到,port和export体现的是控制流而不是数据流。
3)transport操作,a上的端口依然是port,而b上的端口依然是export。a依然是“发起者”,b依然是“目标”。在这个过程中,数据流先从a流向b,再从b流向a。在现实世界中,相当于是a向b提交了一个请求(request),而b返回给a一个应答(response)。所以这种transport操作也常常被称做request-response操作。
put、get和transport操作都有阻塞和非阻塞之分。
port与export
port具有高优先级,而export具有低优先级。只有高优先级的端口才能向低优先级的端口发起三种操作
uvm提供对tlm操作的支持,在其中实现了port与export。对应于不同的操作,有不同的port,uvm中常用的port有
uvm_blocking_put_port#(t);uvm_nonblocking_put_port#(t);uvm_put_port#(t);uvm_blocking_get_port#(t);uvm_nonblocking_get_port#(t);uvm_get_port#(t);uvm_blocking_peek_port#(t);uvm_nonblocking_peek_port#(t);uvm_peek_port#(t);//peek系列端口,它们与get系列端口类似,用于主动获取数据uvm_blocking_get_peek_port#(t);uvm_nonblocking_get_peek_port#(t);uvm_get_peek_port#(t);//集合了get操作和peek操作两者的功能uvm_blocking_transport_port#(req, rsp);uvm_nonblocking_transport_port#(req, rsp);uvm_transport_port#(req, rsp); 这15个端口中前12个定义中的参数就是这个port中的数据流类型,而最后3个定义中的参数则表示transport操作中发起请求时传输的数据类型和返回的数据类型
tlm中的操作,同时以blocking和nonblocking关键字区分。对于名称中不含这两者的,则表示这个端口既可以用作是阻塞的,也可以用作是非阻塞的,否则只能用于阻塞的或者只能用于非阻塞的。
下面的15种export定义与前面的15种port一一对应
来源:uvm源代码uvm_blocking_put_export#(t);uvm_nonblocking_put_export#(t);uvm_put_export#(t);uvm_blocking_get_export#(t);uvm_nonblocking_get_export#(t);uvm_get_export#(t);uvm_blocking_peek_export#(t);uvm_nonblocking_peek_export#(t);uvm_peek_export#(t);uvm_blocking_get_peek_export#(t);uvm_nonblocking_get_peek_export#(t);uvm_get_peek_export#(t);uvm_blocking_transport_export#(req, rsp);uvm_nonblocking_transport_export#(req, rsp);uvm_transport_export#(req, rsp);
port与export的连接
为了实现端口间的通信,uvm 中使用connect 函数来建立连接关系。如a要和b通信(a 是发起者),那么可以这么写:a.port.connect(b.export),但是不能写成b.export.connect(a.port),只有发起者才能调用connect 函数。
举例,a的代码为
文件:src/ch4/section4.2/4.2.1/a.sv3 class a extends uvm_component; `uvm_component_utils(a) uvm_blocking_put_port#(my_transaction) a_port; endclass14 function void a::build_phase(uvm_phase phase); super.build_phase(phase); a_port = new(a_port, this); endfunction19 task a::main_phase(uvm_phase phase); endtask 接一个export。b的代码为
文件:src/ch4/section4.2/4.2.1/b.sv3class b extends uvm_component;`uvm_component_utils(b)uvm_blocking_put_export#(my_transaction) b_export;…endclass function void b::build_phase(uvm_phase phase); super.build_phase(phase); b_export = new(b_export, this); endfunction19 task b::main_phase(uvm_phase phase); endtask 在env中建立两者之间的连接:
文件:src/ch4/section4.2/4.2.1/my_env.sv4 class my_env extends uvm_env;a a_inst;b b_inst;…virtual function void build_phase(uvm_phase phase);…a_inst = a::type_id::create(a_inst, this);b_inst = b::type_id::create(b_inst, this);endfunction…endclassfunction void my_env::connect_phase(uvm_phase phase);super.connect_phase(phase);a_inst.a_port.connect(b_inst.b_export);endfunction
青海正式迈入“互联网+”时代,首家“互联网E时代”充电站落户海北原子城
中银航空租赁宣布交付首架波音737 MAX 9型飞机予最新客户
爱立信提出了一项拟定5G网络国家计划的提案
AMD嵌入式处理器被IGT选定用于新款“CrystalCurve ULTRA”游戏机
投影机便携包该如何使用
TLM通信中常用的术语
利用指纹识别技术读取电源按钮可安全启动无缝过程
打破技术服务壁垒:博联的轻智能家居方案,如何做到以小博大?
AD9643BCPZ-250双通道模数转换器ADC介绍
探索AI制度供给上海责无旁贷
苹果吞下全球手机八成利:家电业如何量利双收
未来智能电网发展趋势
语音芯片倒车喇叭语音播放方案
苹果iPhone14系列不支持WiFi 6E标准
浅谈PCB电路板外形加工钻削工艺
金管局密切监察虚拟银行运作 大约一年作出全面评估
如何准确判断电路中的IC是否工作、好坏
小型贴片功率电感感量较大究竟好不好
LED市场“寒冬”已至?LED显示屏出口一枝独秀
数据转换器的工程师指南