Jump to content

Multiple TLM Implementation Ports

Recommended Posts

I understand that the port declaration macros could be used to define multiple implementation ports in a component:

class my_comp extends uvm_component;
  uvm_put_imp_1 put_imp1;
  uvm_put_imp_2 put_imp2;
endclass : my_comp

However, macros are not amenable to configuration. How can I realize multiple imps in a single component where I could configure the number of the imps using either the config db or a parameter?

// -- Desired
class my_comp extends uvm_component;
  protected int num_imps = 1;
  uvm_put_imp put_imp[];
  `uvm_component_utils(num_imps, UVM_DEFAULT)
endclass : my_comp
Link to comment
Share on other sites

Well, remember that if you declare multiple imps, then you need to write separate imp functions for each one:

function void put_1(blah);
endfunction : put_1

function void put_2(blah);
endfunction : put_2

Maybe this is what you want, I don't know. But in this case, then the thing to do is to implement all possible ones, and then during the build_phase, only new() the ones you need, and during the connect_phase(), only connect those.

On the other hand, you may wish to process all those blah values in the same manner, and you don't want to have to write all of those functions, you just want one of those functions. In that case, you implement just one imp, and just one function, and you use some identifier inside of blah to help you out:

class my_comp extends uvm_component;
  uvm_put_imp put_imp;
  function void put(blah);
endfunction : put
Link to comment
Share on other sites


You should be able to achieve same intention without macros by putting some FIFOs as below.

class xx extends uvm_component;
uvm_analysis_export #(itm) export[];
uvm_tlm_analysis_fifo #(itm) fifo1[];

// skip new() … 

function void connect()
  for (...)

// in run(), use fifo[n].get( blah...)

Link to comment
Share on other sites


there are a few things mixed here:

- a particular 'imp' port type is always calling a specific function in the supplied container (2nd arg of the imp, usually the enclosing component). this means multiple instances of the same imp are connected to the same function in the enclosing component.

- the *decl* marcos simply pre/post fix the port imp type name AND the function which is called in the container. so normally an put_imp would end up in put() but with decl of (_post) it ends up in put_post() instead).

- imp-port-type to target function relation is usually N:1 (this also means you cant have instances of an imp of item type A and B at the same time).

to get around and have N:M connections you basically got 3 ways

1. separation via the decl macros: (this makes new imp port base types and new target functions which are called)

2. you create a meta-transaction which holds your real transaction(s). in the target you unpack the meta transaction based upon a selector field like an target index,....: (this makes an explicit N:1 connection and you handle the transaction target locally)

3. you create a proxy using the uvm_subscriber(or similar). for a N:M connection you simply instantiate M proxies in your target. each proxy is handling then one endpoint alone.


Link to comment
Share on other sites

Another option you may have is to redefine the imp "decl" macro to add an identifier to the class that it defines. And in this class, you can call "write(trans, id)" instead of just "write(trans)".

Sounds like you may want to declare an array of implementations. So the "id" in this case can be the array index and can be initialized to the proper index value when you create/new the imp objects. Then your implementation of the write function can decide what do do with "id"...

Hope that made sense...

Link to comment
Share on other sites

Thanks, y'all, for all the help and useful info. I think Uwe summarized the options very well. I think the best option for me to try is what Sean proposed, which appears similar to #3 in Uwe's summary, to use a proxy class such as uvm_tlm_analysis_fifo or uvm_subscriber.

Link to comment
Share on other sites

  • 1 month later...

I don't agree 100% with all I am reading here.

The export/analysis_fifo was and still is a sensible way to do things, and is how it was done in AVM back 5 yrs ago.

OVM put forward the "imp" and added the "decl" macros. It still didn't provide the required functionality => hence this post.

I would also add that is confuse new adopters.

The subscriber indeed offers the same functionality.

Connecting components should be straight forward and not require a post on this forum. I would suggest to no longer promote the use these "decl" macros.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...