包含有analysis_port和analysis_export两种端口,它们与port、export和imp的主要区别在于:
第一,默认情况下,analysis_port(analysis_export)可以连接多个IMP,而put和get系列端口连接一个IMP(除非在例化时修改连接数量)。
第二,analysis_port和analysis_export没有阻塞与非阻塞之分,而put和get系列端口有阻塞与非阻塞之分。
第三,put系列端口有put、try_put和can_put等 *** 作;get系列端口有get、try_get和can_get等 *** 作;analysis_port和analysis_export端口只有一种 *** 作:write。在analysis_imp所在的component,必须定义一个名字为write的函数。
2、analysis 端口连接关系A的代码:
class A extends uvm_component; `uvm_component_utils(A); uvm_analysis_port#(my_transaction) A_ap;//定义端口类型 endclass function void A::build_phase(uvm_phase phase); super.build_phase(phase); A_ap = new("A_port",this);//例化端口 endfunction task A::main_phase(uvm_phase phase); my_transaction tr; tr = new("tr"); assert(tr.randomize()); A_ap.write(tr);//发送tr数据包 endtask
B的代码:
class B extends uvm_component; `uvm_component_utils(B); uvm_analysis_imp#(my_transaction,B) B_imp;//定义端口类型 endclass function void B::build_phase(uvm_phase phase); super.build_phase(phase); B_imp = new("B_imp",this); endfunction function void B::write(my_transaction tr); tr.print(); endfunction
在env中建立起两者的连接:
class my_env extends uvm_env; A A_inst; B B_inst; endclass function void my_env::build_phase(uvm_phase phase); super.build_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); endfunction3、特别说明
与put系列端口的PORT和EXPORT直接相连出错一样,analysis_port与analysis_export直接相连也会出错,只有在analysis_export后面连接一级analysis_imp才不会出错。
4、uvm_analysis_imp_decl宏的使用当出现analysis_imp所在的component需要接收多路数据的情况时,但write只有一个,那么该如何定义write函数呢?这时就用到了宏uvm_analysis_imp_decl。例子如下:
`uvm_analysis_imp_decl(_monitor) `uvm_analysis_imp_decl(_model) class my_scoreboard extends uvm_scoreboard; my_transaction tr; 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); endclass function void my_scoreboard::write_monitor(my_transaction tr); endfunction function void my_scoreboard::write_model(my_transaction tr); endfunction
只要完成后缀的声明,并在write后面加上相应的后缀即可正常工作。
5、使用fifo通信fifo的本质是一个缓存加两个IMP,例子如下:
class my_scoreboard extends uvm_scoreboard; my_transaction tr; my_transaction get_exp; my_transaction get_act; uvm_blocking_get_port#(my_transaction) exp_port; uvm_blocking_get_port#(my_transaction) act_port; endclass task my_scoreboard::main_phase(phase); fork while(1)begin exp_port.get(get_exp);//获取数据包 end while(1)begin act_port.get(get_act);//获取数据包 end join endtask
在env中建立起连接:
```typescript class my_env extends uvm_env; my_agent i_agt; my_agent o_agt; my_scoreboard scb; my_model mdl; uvm_tlm_analysis_fifo#(my_transaction ) agt_scb_fifo; uvm_tlm_analysis_fifo#(my_transaction ) agt_mdl_fifo; uvm_tlm_analysis_fifo#(my_transaction ) mdl_scb_fifo; endclass function void my_env::connect_phase(uvm_phase phase); super.connect_phase(phase); i_agt.A_ap.connect(agt_mdl_fifo.analysis_export);//input monitor->fifo mdl.port.connect(agt_mdl_fifo.blocking_get_export);//fifo->model mdl.ap.connect(mdl_scb_fifo.analysis_export);//model->fifo scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);//fifo->scoreboard o_agt.A_ap.connect(agt_scb_fifo.analysis_export);//output monitor -> fifo scb.act_port.connect(agt_scb_fifo.blocking_get_export);//fifo->scoreboard endfunction
使用fifo连接之后,scoreboard可以按照自己的节奏工作,而不用去适应monitor的节奏。同时也不用建立两个write函数,省去了好多麻烦。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)