公司动态

【UVM】TLM通信机制

📅 2026/7/22 16:31:52
【UVM】TLM通信机制
基本概念TLMtransaction level modeling是一个基于事务transaction的通信方式每次传输一个transaction一个transaction就是把具有某一特定功能的一组信息封装在一起而成为的一个类。通信对象发起者数据的请求方也就是initiator响应者数据的响应方也就是target注发起者和响应者不代表数据的流向性。initiator永远有主动权不论时请求数据还是主动发送数据永远是发起的那一方target永远时被动的只能被动的接收数据或者被通知需要发送数据传输方式put操作单向传输通信动作发起者A把一个transaction发送给B数据流从A流向Bget操作单向传输通信动作发起者A向B索取一个transaction数据流从B流向Atransport操作双向传输又称做request-response操。相当于一次put操作加一次get操作这两次操作的“发起者”都是A目标都是B数据从A流到B再从B流向A。通信端口端口定义port端口initiator的端口有阻塞赋值和非阻塞赋值的区分export端口initiator和target的中转端口有阻塞赋值和非阻塞赋值的区分imp端口target端口有阻塞赋值和非阻塞赋值的区分注意端口优先级port export imp在connect_phase中使用connect()建立连接关系时只有优先级高的才能调用connect()做连接即port可以连接port、export或者impexport可以连接export或者impimp只能作为数据传送的重点无法扩展连接在UVM中只有IMP才能作为连接关系的终点UVM常见端口PORT端口//blocking阻塞nonblocking非阻塞不含这两者表示既可以阻塞也可以非阻塞 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); uvm_blocking_get_peek_port#(T); uvm_nonblocking_get_peek_port#(T); uvm_get_peek_port#(T); uvm_blocking_transport_port#(REQ, RSP); uvm_nonblocking_transport_port#(REQ, RSP); uvm_transport_port#(REQ, RSP);EXPORT端口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);IMP端口//IMP定义中的blocking、nonblocking、put、get、peek、get_peek、transport等关键字的意思并不是它们发起做相应类型的操作而只意味着它们可以和相应类型的PORT或者EXPORT进行通信 //每一个IMP需要和一个component相对应 uvm_blocking_put_imp#(T, IMP); uvm_nonblocking_put_imp#(T, IMP); uvm_put_imp#(T, IMP); uvm_blocking_get_imp#(T, IMP); uvm_nonblocking_get_imp#(T, IMP); uvm_get_imp#(T, IMP); uvm_blocking_peek_imp#(T, IMP); uvm_nonblocking_peek_imp#(T, IMP); uvm_peek_imp#(T, IMP); uvm_blocking_get_peek_imp#(T, IMP); uvm_nonblocking_get_peek_imp#(T, IMP); uvm_get_peek_imp#(T, IMP); uvm_blocking_transport_imp#(REQ, RSP, IMP); uvm_nonblocking_transport_imp#(REQ, RSP, IMP); uvm_transport_imp#(REQ, RSP, IMP);通信方式一对一通信port-export-imp基本概念类型port-imp互联export-imp互联port-port互联PORT与PORT之间的连接可以有无限多层。export-export互联EXPORT与EXPORT之间的连接可以有无限多层端口互联对应关系发起者(port/export/transport)类型imp中对应的任务/函数blocking_putputnonblocking_puttry_put和can_putputput、try_put和can_putblocking_getgetnonblocking_gettry_get和can_getgetget、try_get和can_getblocking_peekpeeknonblocking_peektry_peek和can_peekpeekpeek、try_peek和can_peekblocking_get_peekget和peeknonblocking_get_peektry_get和can_get、try_peek和can_peekget_peekget和peek、try_get和can_get、try_peek和can_peekblocking_transporttransportnonblocking_transportnb_transporttransporttransport和nb_transport注对于blocking的端口可以定义相应的任务或函数对于nonblocking端口只能定义函数一对多通信analysis_port/analysis_export/analysis_imp基本概念一个analysis_portanalysis_export可以连接多个analysis_imp对于analysis_port和analysis_export来说没有阻塞和非阻塞的概念analysis_port如果和analysis_export直接相连也会出错只有在analysis_export后面再连接一级uvm_analysis_imp才不会出错端口互联对应关系analysis_port和analysis_export类型analysis_imp对应函数*write注对于同一个component下需要用到多个uvm_analysis_imp的场景解决方式可通过定义宏uvm_analysis_imp_decl_xxx声明多个后缀不一样的impUVM会根据后缀内建不同的imp。//my_scoreboard.sv uvm_analysis_imp_decl(_monitor) uvm_analysis_imp_decl(_model) class my_scoreboard extends uvm_scoreboard; my_transaction expect_queue[$]; uvm_analysis_imp_monitor#(my_transaction, my_scoreboard) monitor_imp; uvm_analysis_imp_model#(my_transaction, my_scoreboard) model_imp; ... extern function void write_monitor(my_transaction tr); extern function void write_model(my_transaction tr); extern virtual task main_phase(uvm_phase phase); endclass function void my_scoreboard::write_model(my_transaction tr); expect_queue.push_back(tr); endfunction function void my_scoreboard::write_monitor(my_transaction tr); my_transaction tmp_tran; bit result; if(expect_queue.size() 0) begin ... end endfunctionFIFO通信基本概念uvm_analysis_fifo本质是一块缓存加两个imp类型端口类型区别uvm_tlm_fifo无以下uvm_tlm_analysis_fifo有一个analysis_export端口及其配套的write函数FIFO端口FIFO中端口有关键字export但是其类型却是IMP。如analysis_export的原型如下uvm_analysis_imp #(T, uvm_tlm_analysis_fifo #(T)) analysis_export;FIFO中的get端口get任务被调用时FIFO内部缓存中会少一个transactionFIFO中的peek端口peek任务被调用时FIFO会把transaction复制一份发送出去其内部缓存中的transaction数量并不会减少当FIFO中的put端口被连接时FIFO内部被定义的put任务被调用它把传递过来的transaction放在FIFO内部的缓存里同时把这个transaction通过put_ap使用write函数发送出去virtual task put( input T t ); m.put( t ); put_ap.write( t ); endtask与put_ap相似当FIFO的get任务被调用时同样会有一个transaction从get_ap上发出virtual task get( output T t ); m_pending_blocked_gets; m.get( t ); m_pending_blocked_gets--; get_ap.write( t ); endtaskFIFO调试函数函数作用used查询FIFO缓存中有多少transactionis_empty判断当前FIFO缓存是否为空is_full判断当前FIFO缓存是否为满flush清空FIFO缓存中的所有数据它一般用于复位等操作//FIFO的new函数原型 function new(string name, uvm_component parent null, int size 1); //第三个参数size用于设定FIFO缓存的上限默认的情况下为1。若要把缓存设置为无限大小将传入的size参数设置为0即可。通过size函数可以返回这个上限值。FIFO与IMP对比FIFO对于初学者使用方式比IMP简洁易上手FIFO连接的方式增加了env中代码的复杂度对于使用端口数组的情况FIFO要优于IMP