uvm_tlm通信
TLM(transaction level modeling)是一个基于事务(transaction)的通信方式。是各个组件之间进行事务传输的方式。
1、三种端口
两个组件通信可将两者分为:
producer:生产数据方,即为producer;
consumer:接收数据方,即为consumer;
根据数据发送请求发起方不同可以大致分为三种端口:
(1)port:通信请求的端口。
(2)export:作为发起请求和接受请求的中间层次端口(可做为中间级连接port和imp)。
(3)imp:只能作为接收请求的响应端。
端口优先级:port > export > imp, 使用connect()建立连接关系时,只有优先级高的才能调用connect()做连接。比如:p.put_port.connect(c.put_imp);
2、连接方式
2.1put模式:
数据请求由producer发起,通过调用consumer中的put函数建立起连接。红色为port端口,绿色为imp端口。事务传输方向为箭头指向方向。
class transaction extends uvm_transaction; //传输数据包
int id;
int data;
...
endclass
class producer extends uvm_component; //数据生产方producer
...
uvm_blocking_put_port#(transaction) put_port; //定义端口
function void build_phase(uvm_phase phase);
put_port = new("put_port",this); //创建实例化端口
endfunction
task run_phase(uvm_phase phase);
put_port.put(tr); //通过数据接收方consumer提供的任务put()处理数据,然后通过TLM传输数据过去
endtask
endclass
class consumer extends uvm_component; //数据接收方consumer
...
uvm_blocking_put_imp#(transaction, consumer) put_imp; //定义端口
function void build_phase(uvm_phase phase);
put_imp = new("put_imp",this); //创建实例化端口
endfunction
virtual task put(transaction tr); //数据生产方producer会调用接收方consumer定义的put()任务
process(tr); //通过数据接收方consumer提供的任务put()处理数据
endtask
endclass
class environment extends uvm_env; //环境层
...
producer p; //数据生产方
consumer c; //数据接收方
...
virtual function void connect_phase(uvm_phase phase);
p.put_port.connect(c.put_imp); //建立连接
endfunction
endclass
2.2get模式
数据请求由consumer发起,通过调用producer中的get函数建立起连接。红色为port端口,绿色为imp端口。事务传输方向为箭头指向方向。
class transaction extends uvm_transaction; //传输数据包
int id;
int data;
...
endclass
class producer extends uvm_component; //数据生产方producer
...
uvm_blocking_get_imp#(transaction,producer) get_imp; //定义端口
function void build_phase(uvm_phase phase);
get_imp = new("put_imp",this); //创建实例化端口
endfunction
virtual task get(output transaction tr); //在imp端口所在component中定义get()任务或者方法,output方向
tr = transaction::type_id::create("tr",this);
endtask
endclass
class consumer extends uvm_component; //数据接收方consumer
...
uvm_blocking_get_port#(transaction, consumer) get_port; //定义端口
function void build_phase(uvm_phase phase);
put_imp = new("put_imp",this); //创建实例化端口
endfunction
task run_phase(uvm_phase phase);
get_port.get(tr); //通过imp所在component定义的get()处理数据,然后通过TLM传输数据
endtask
endclass
class environment extends uvm_env; //环境层
...
producer p; //数据生产方
consumer c; //数据接收方
...
virtual function void connect_phase(uvm_phase phase);
c.get_port.connect(p.get_imp); //建立连接
endfunction
endclass
2.3fifo模式
fifo之前采用put模式接口,后端采用get模式接口。
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
virtual dut_interface m_vif;
uvm_blocking_put_port #(my_transaction) m2r_port;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.m2r_port = new("m2r_port", this);
endfunction
task run_phase(uvm_phase phase);
put_port.put(tr); //通过数据接收方consumer提供的任务put()处理数据,然后通过TLM传输数据过去
endtask
endclass
class master_agent extends uvm_agent;
`uvm_component_utils(master_agent)
my_sequencer m_seqr;
my_driver m_driv;
my_monitor m_moni;
uvm_blocking_put_export #(my_transaction) m_a2r_export;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.m_a2r_export = new("m_a2r_export", this);
endfunction
virtual function void connect_phase(uvm_phase phase);
if(is_active == UVM_ACTIVE)
m_driv.seq_item_port.connect(m_seqr.seq_item_export);
m_moni.m2r_port.connect(this.m_a2r_export);
endfunction
endclass
class my_reference_model extends uvm_component;
`uvm_component_utils(my_reference_model)
uvm_blocking_get_port #(my_transaction) i_m2r_port;
my_transaction item;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.i_m2r_port = new("i_m2r_port", this);
endfunction
virtual task run_phase(uvm_phase phase);
`uvm_info("REF_MODEL_RUN", "Refernece model running !", UVM_MEDIUM)
forever begin
i_m2r_port.get(item);
`uvm_info("REF_REPORT", {"\n", "master agent have been sent a transaction: \n", item.sprint()}, UVM_MEDIUM);
end
endtask
endclass
class my_env extends uvm_env;
`uvm_component_utils(my_env)
master_agent m_agent;
my_reference_model ref_model;
uvm_tlm_analysis_fifo #(my_transaction) magt2ref_fifo;//fifo
function new(string name = "", uvm_component parent);
super.new(name, parent);
magt2ref_fifo = new("magt2ref", this);//实例化
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("ENV", "Connect the agent to fifo...", UVM_MEDIUM)
m_agent.m_a2r_export.connect(this.magt2ref_fifo.blocking_put_export);
`uvm_info("ENV", "Connect the reference model to fifl...", UVM_MEDIUM)
ref_model.i_m2r_port.connect(this.magt2ref_fifo.blocking_get_export);
endfunction
endclass
通信通道图解
monitor与modle之间的通信通过fifo模式,agent的端口为export为中间级。出現了跨层次传输,agent为中间层也需要设置端口。
2.4analysis_port
该通信方式与以上三种不同,以上三种属于一对一传输,该种方式为一对多。
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
virtual dut_interface m_vif;
uvm_analysis_port #(my_transaction) m2r_a_port;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.m2r_a_port = new("m2r_a_port", this);
endfunction
task run_phase(uvm_phase phase);
m2r_a_port.write(tr); //通过数据接收方consumer提供的任务write()处理数据,然后通过TLM传输数据过去
endtask
endclass
class master_agent extends uvm_agent;
`uvm_component_utils(master_agent)
my_sequencer m_seqr;
my_driver m_driv;
my_monitor m_moni;
agent_config m_agent_cfg;
uvm_analysis_port #(my_transaction) m_a2r_a_port;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.m_a2r_a_port = new("m_a2r_a_port", this);
endfunction
virtual function void connect_phase(uvm_phase phase);
if(is_active == UVM_ACTIVE)
m_driv.seq_item_port.connect(m_seqr.seq_item_export);
m_moni.m2r_a_port = this.m_a2r_a_port;
endfunction
endclass
class my_reference_model extends uvm_component;
`uvm_component_utils(my_reference_model)
uvm_analysis_imp #(my_transaction, my_reference_model) i_m2r_a_imp;
my_transaction item;
function new(string name = "", uvm_component parent);
super.new(name, parent);
this.i_m2r_a_imp = new("i_m2r_a_imp", this);
endfunction
task write(my_transaction tr);
`uvm_info("REF_REPORT", {"\n", "master agent have been sent a transaction: \n", tr.sprint()}, UVM_MEDIUM);
endtask
endclass
class my_env extends uvm_env;
`uvm_component_utils(my_env)
master_agent m_agent;
env_config m_env_cfg;
// agent_config m_agent_cfg;
my_reference_model ref_model;
function new(string name = "", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("ENV", "Connect the agent and reference model...", UVM_MEDIUM)
m_agent.m_a2r_a_port.connect(ref_model.i_m2r_a_imp);
endfunction
endclass
四种通信方式完整的构成了UVM的事物传输。