大家好,欢迎来到IT知识分享网。
目录
1.4 ANALYSIS_PORT(EXPORT) & ANALYSIS_IMP
2.1 一对一(PORT–EXPORT–IMP)单向端口通信
2.2 一对多(ANALYSIS_PORT–ANALYSIS_IMP)单向端口通信
1. 基本概念
1.1 TLM定义
TLM(Transaction Level Modeling)是源于SystemC的一种通信标准,这种通信方式每次传输一个transaction,一个transaction是指将一组信息(如地址,数据等等)封装成一个包发送出去,参数如下代码。
class simple_trans extends uvm_sequence_item; rand data_t data; rand addr_t addr; rand enum {WRITE,READ} kind; constraint c1 { addr < 16’h2000; } ... endclass
1.2 put & get & transport 操作
put操作:通信动作发起者A将一个transaction发送给通信动作接收者B,A的端口称为PORT,B的端口称为EXPORT,数据流从A流向B;
get操作:通信动作发起者A向B索取一个transaction,数据流从B流向A;
transport操作:通信动作发起者A向B提交了通信请求,B返还给A一个transaction,数据从A流到B,再从B流向A,相当于一次put加get操作;
1.3 PORT & EXPORT & IMP
PORT端口:通信动作发起者的端口,有阻塞赋值和非阻塞赋值的区分,优先级高于EXPORT;常用的UVM PORT类型如下:
#参数T代表要传输的类型 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端口: 通信动作中转方,有阻塞赋值和非阻塞赋值的区分,优先级高于IMP,常用的UVM EXPORT有:
#参数T代表要传输的类型 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端口:通信动作接收方,有阻塞赋值和非阻塞赋值的区分,优先级最低,常用的UVM IMP有:
#参数T代表要传输的类型 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可以连接到一个IMP,并发起三种操作,反之不行;15种PORT,EXPORT,IMP一一对应。
1.4 ANALYSIS_PORT(EXPORT) & ANALYSIS_IMP
analysis_port(export)和port端口类似,区别如下:
1)一个analysis_port可以连接多个analysis_imp;
2)没有阻塞赋值和非阻塞赋值的区分;
3)只有write一种通信操作;
1.5 阻塞赋值与非阻塞赋值
阻塞赋值(blocking):通信动作发起方发起的request未被响应,会一直等待接收方的响应,直至request被响应才能发起下一个request,阻塞时会消耗时间;
非阻塞赋值(nonblocking):通信动作发起方不关心第一个request是否被响应,会继续发下一个request;
2. UVM通信方式
2.1 一对一(PORT–EXPORT–IMP)单向端口通信
通过connect函数建立起port-export-imp的关系,从而进行一对一端口通信;
只有通信动作发起方才可以调用connect函数;
imp端口必须作为通信的最后节点;
1)port-export-imp端口相连,在B的代码里必须定义put函数,否则会出错,代码如下:
//A.sv class A extends uvm_component; `uvm_component_utils(A) uvm_blocking_put_port#(my_transaction) A_port; ... endclass task A::main_phase(uvm_phase phase); my_transaction tr; repeat(10) begin #10; tr = new("tr"); assert(tr.randomize()); A_port.put(tr); end endtask //B.sv class B extends uvm_component; `uvm_component_utils(B) uvm_blocking_put_export#(my_transaction) B_export; uvm_blocking_put_imp#(my_transaction, B) B_imp; ... endclass function void B::connect_phase(uvm_phase phase); super.connect_phase(phase); B_export.connect(B_imp); endfunction function void B::put(my_transaction tr); `uvm_info("B", "receive a transaction", UVM_LOW) tr.print(); endfunction //my_env.sv class my_env extends uvm_env; A A_inst; B_inst; ... endclass 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 ... function void my_env::connect_phase(uvm_phase phase); super.connect_phase(phase); A_inst.A_port.connect(B_inst.B_export); endfunction
2)port-imp端口相连,根据A.sv种PORT端口的类型决定在B.sv种定义哪种put/get函数,详见下表
端口类型 | 定义函数类型 |
uvm_blocking_put | task put(T t) |
uvm_nonblocking_put | function bit try_put(T t)与function bit can_put() |
uvm_blocking_get | task get(output T t) |
uvm_nonblocking_put | function bit try_get(output T t)与function bit can_get() |
… | … |
参考代码如下(uvm_blocking_put类型):
//A.sv和my_env.sv的代码保持不变 //B.sv class B extends uvm_component; `uvm_component_utils(B) uvm_blocking_put_imp#(my_transaction, B) B_imp; ... endclass function void B::put(my_transaction tr); `uvm_info("B", "receive a transaction", UVM_LOW) tr.print(); endfunction
2.2 一对多(ANALYSIS_PORT–ANALYSIS_IMP)单向端口通信
1)analysis_port支持一对一,一对多通信,需要在B.sv中定义一个write函数,示例代码如下:
//A.sv class A extends uvm_component; `uvm_component_utils(A) uvm_analysis_port#(my_transaction) A_ap; ... endclass task A::main_phase(uvm_phase phase); my_transaction tr; repeat(10) begin #10; tr = new("tr"); assert(tr.randomize()); A_ap.write(tr); end endtask //B.sv class B extends uvm_component; `uvm_component_utils(B) uvm_analysis_imp#(my_transaction, B) B_imp; ... endclass function void B::write(my_transaction tr); `uvm_info("B", "receive a transaction", UVM_LOW) tr.print(); endfunction //my_env.sv class my_env extends uvm_env; A A_inst; B_inst; ... endclass 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 ... function void my_env::connect_phase(uvm_phase phase); super.connect_phase(phase); A_inst.A_ap.connect(B_inst.B_imp); A_inst.A_ap.connect(C_inst.C_imp);//一个port连接多个imp,C的定义和B类似 endfunction
2) 一个component有多个IMP,使用imp_decl,示例如下:
//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 endfunction
2.3 FIFO双向通信
待更新
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/127115.html