ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

日常记录(42)TLM、

2022-01-18 09:04:15  阅读:265  来源: 互联网

标签:transaction tr 42 imp inst 日常 put port TLM


TLM的put

my_case的main_phase中设定了raise_objection,并延时1000仿真单位后,drop,后续代码中的main_phase不设定raise和drop。

TLM的demo,(port->export->imp)

在A和B之间通信,首先在env中构建对应的实例(在不同的phase中),

然后给连接,A的port给数据到B的export中。

   A   A_inst;
   B   B_inst;
A_inst = A::type_id::create("A_inst", this);
B_inst = B::type_id::create("B_inst", this);

   A_inst.A_port.connect(B_inst.B_export);

A中,

定义port,使用put发送。

   uvm_blocking_put_port#(my_transaction) A_port;

   A_port = new("A_port", this);

      tr = new("tr");
      assert(tr.randomize());
      A_port.put(tr);

B中,

定义export,imp,进行连接,使用imp接收,其中imp连接到其put函数,最终连接到B的put函数。

   uvm_blocking_put_export#(my_transaction) B_export;
   uvm_blocking_put_imp#(my_transaction, B) B_imp;

   B_export = new("B_export", this);
   B_imp = new("B_imp", this);

   B_export.connect(B_imp);


function void B::put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   tr.print();
endfunction

  

port->imp

env中连接

   A_inst.A_port.connect(B_inst.B_imp);

A不变

   uvm_blocking_put_port#(my_transaction) A_port;

   A_port = new("A_port", this);

      tr = new("tr");
      assert(tr.randomize());
      A_port.put(tr);

B只有imp,然后是put函数

   uvm_blocking_put_imp#(my_transaction, B) B_imp;
   B_imp = new("B_imp", this);

function void B::put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   tr.print();
endfunction

  

注意:blocking_put类型,使用了put函数。如果是nonblocking_put,使用需要try_put和can_put两个函数;如果只有put,则需要以上三个函数。

如果为get类型,则需要对应的get函数。peek同理。get和peek同时(如blocking_get_peek),则同样结合二者需要的函数定义。

如果为transport,对应transport函数,非阻塞使用nb_transport函数。

阻塞部分不仅可以定义成函数,还可以定义成任务。

 

export->imp

env中,

   A   A_inst;
   B   B_inst;

      A_inst = A::type_id::create("A_inst", this);
      B_inst = B::type_id::create("B_inst", this);

   A_inst.A_export.connect(B_inst.B_imp);

A中,

main_phase中为什么不用raise_objection

   uvm_blocking_put_export#(my_transaction) A_export;

   A_export = new("A_export", this);

      tr = new("tr");
      assert(tr.randomize());
      A_export.put(tr);

B不变

   uvm_blocking_put_imp#(my_transaction, B) B_imp;
   B_imp = new("B_imp", this);

function void B::put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   tr.print();
endfunction

  

port->port->imp

C的port发送给A的port,然后A的port发送给B的imp

env中,

   A   A_inst;
   B   B_inst;

      A_inst = A::type_id::create("A_inst", this);
      B_inst = B::type_id::create("B_inst", this);

   A_inst.A_port.connect(B_inst.B_imp);

C中,

   uvm_blocking_put_port#(my_transaction) C_port;

   C_port = new("C_port", this);

task C::main_phase(uvm_phase phase);
   my_transaction tr;
   repeat(10) begin
      #10;
      tr = new("tr");
      assert(tr.randomize());
      C_port.put(tr);
   end
endtask

A中,

由谁发出数据,就由谁作为主动连接的connect调用。

   C C_inst;
   uvm_blocking_put_port#(my_transaction) A_port;
A_port = new("A_port", this); C_inst = C::type_id::create("C_inst", this); C_inst.C_port.connect(this.A_port);

B中,不变

   uvm_blocking_put_imp#(my_transaction, B) B_imp;

   B_imp = new("B_imp", this);

function void B::put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   tr.print();
endfunction

  

port->export->export->imp

env中,

   A   A_inst;
   C   C_inst;

      A_inst = A::type_id::create("A_inst", this);
      C_inst = C::type_id::create("B_inst", this);

   A_inst.A_port.connect(C_inst.C_export);

A中,

   uvm_blocking_put_port#(my_transaction) A_port;

   A_port = new("A_port", this);

      tr = new("tr");
      assert(tr.randomize());
      A_port.put(tr);

C中,

   B B_inst;

   uvm_blocking_put_export#(my_transaction) C_export;

   C_export = new("C_export", this);
   B_inst = B::type_id::create("B_inst", this); 

   this.C_export.connect(B_inst.B_export);

B中,

   uvm_blocking_put_export#(my_transaction) B_export;
   uvm_blocking_put_imp#(my_transaction, B) B_imp;

   B_export = new("B_export", this);
   B_imp = new("B_imp", this);

   B_export.connect(B_imp);

function void B::put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   tr.print();
endfunction

  

TLM的get、transport、non_blocking

(get)A的imp->export->B的port(数据流向)

B为动作的发起者,A为被动从imp发送数据的动作接收者(B的port,A的export,A的imp控制流向)

imp作为动作的最终点。

my_env中,

   A   A_inst;
   B   B_inst;

      A_inst = A::type_id::create("A_inst", this);
      B_inst = B::type_id::create("B_inst", this);

   B_inst.B_port.connect(A_inst.A_export);

B中,

   uvm_blocking_get_port#(my_transaction) B_port;

   B_port = new("B_port", this);

      B_port.get(tr);
      `uvm_info("B", "get a transaction", UVM_LOW) 
      tr.print();

A中,

   uvm_blocking_get_export#(my_transaction) A_export;
   uvm_blocking_get_imp#(my_transaction, A) A_imp;
   my_transaction tr_q[$];


A_export = new("A_export", this);
A_imp = new("A_imp", this);


A_export.connect(A_imp);


task A::get(output my_transaction tr);
   while(tr_q.size() == 0) #2;
   tr = tr_q.pop_front();
endtask

task A::main_phase(uvm_phase phase);
   my_transaction tr;
   repeat(10) begin
      #10;
      tr = new("tr");
      tr_q.push_back(tr); 
   end
endtask

  

(transport)A的transport->B的imp(数据双向)

动作从A->B

在env中,

   A   A_inst;
   B   B_inst;

      A_inst = A::type_id::create("A_inst", this);
      B_inst = B::type_id::create("B_inst", this);

   A_inst.A_transport.connect(B_inst.B_imp);

在A中,

   uvm_blocking_transport_port#(my_transaction, my_transaction) A_transport;

   A_transport = new("A_transport", this);

task A::main_phase(uvm_phase phase);
   my_transaction tr;
   my_transaction rsp;
   repeat(10) begin
      #10;
      tr = new("tr");
      assert(tr.randomize());
      A_transport.transport(tr, rsp);
      `uvm_info("A", "received rsp", UVM_MEDIUM)
      rsp.print();
   end
endtask

在B中,

   uvm_blocking_transport_imp#(my_transaction, my_transaction, B) B_imp;

   B_imp = new("B_imp", this);

task B::transport(my_transaction req, output my_transaction rsp);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   req.print();
   //do something according to req
   #5;
   rsp = new("rsp");
endtask

  

non_blocking通信。A的port->B的imp

env中,常规

   A   A_inst;
   B   B_inst;

      A_inst = A::type_id::create("A_inst", this);
      B_inst = B::type_id::create("B_inst", this);

   A_inst.A_port.connect(B_inst.B_imp);

A中,

可以直接使用try_put即可,附带了判断功能,通过则直接发送

   uvm_nonblocking_put_port#(my_transaction) A_port;

   A_port = new("A_port", this);

task A::main_phase(uvm_phase phase);
   my_transaction tr;
   repeat(10) begin
      tr = new("tr");
      assert(tr.randomize());
      while(!A_port.can_put()) #10;
      void'(A_port.try_put(tr));
   end
endtask

B中,

需要定义can_put和try_put函数。然后接收过程中,使用非阻塞(获取数据暂存队列),然后调用队列。

   uvm_nonblocking_put_imp#(my_transaction, B) B_imp;
   my_transaction tr_q[$];

   B_imp = new("B_imp", this);

function bit B::can_put();
   if(tr_q.size() > 0)
      return 0;
   else 
      return 1;
endfunction

function bit B::try_put(my_transaction tr);
   `uvm_info("B", "receive a transaction", UVM_LOW) 
   if(tr_q.size() > 0)
      return 0;
   else begin
      tr_q.push_back(tr);
      return 1;
   end
endfunction

task B::main_phase(uvm_phase phase);
    my_transaction tr;
    while(1) begin
       if(tr_q.size() > 0)
          tr = tr_q.pop_front();
       else
          #25;
    end
endtask

  

analysis的port

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

标签:transaction,tr,42,imp,inst,日常,put,port,TLM
来源: https://www.cnblogs.com/bai2022/p/15816270.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有