Jump to content

TLM connections: sequencer to component and component to driver

Recommended Posts

hello all,

this is a real "how to" question as i have very little experience at UVM

in my environment i have a need of having a uvm_component between the sequencer and driver, i can elaborate later what is the reason to do that.

i didn't find a reasonable explanation of how to implement that.

i need to use nonblocking pull mode ports (driver "try_get" from component, component "try_get" from sequencer).

i would appreciate a good explanation about that issue,


Link to comment
Share on other sites

To put it simply, your component will need to be a driver and a sequencer (generally you would use "sequencer layering" for this instead).

class adapter_comp#(type REQ=int, type RSP=REQ);

`uvm_component_param_utils(adapter_comp#(type REQ=int, type RSP=REQ))

typedef adapter_comp#(REQ,RSP) this_type;

uvm_seq_item_pull_imp #(REQ, RSP, this_type) out_seq_item_export;

uvm_seq_item_pull_port#(REQ, RSP) in_seq_item_port;

// implement the seq_item_export tasks

virtual task try_next_item (output REQ t);

in_seq_item_port.try_next_item( t );


// etc.


Link to comment
Share on other sites

thank you very much

it's very helpful, and it solves half of my problems

the component is connected to a sequencer in one side, and two drivers in the other (that's why i need a component in the middle, to be like a splitter)

the question is: how do i implement 2 "try_next_item" functions for both exports?


try_next_item is a function and not a task, right?

thanks again

Link to comment
Share on other sites

There's no imp macro for this tlm port type so you'll have to extend it yourself. You can either have your extension call a different task (like the uvm imp macros do) or have it add an argument to the called task to identify the port.

While try_next_item is non-blocking when no transaction is available, it awakens the sequence body task for next transaction (which also shouldn't consume time, but does involve a delta cycle) thus it needs to be a task.

Link to comment
Share on other sites

Here's an example using multiple analysis ports:

class my_scoreboard extends uvm_component;
  class my_imp extends uvm_analysis_export#(my_obj);
  my_scoreboard parent;
  int ndx;
  function new( string name, my_scoreboard parent, int ndx );
    super.new( name, parent );
    this.parent = parent;
    this.ndx = ndx;
  function void write( my_obj t );
    parent.write( ndx, t );

  my_imp in_port[];
  int num_ports = 3;

    `uvm_field_int(num_ports, UVM_DEFAULT)

  function new( string name, uvm_component parent );
    super.new( name, parent );

  function void build();
    in_port = new[num_ports];
    for( int i = 0; i < num_ports; i++ ) begin
      in_port[i] = new( $psprintf( "in_port[%0d]", i ), this, i );

  function void write( int ndx, my_obj t );
    // do whatever


But I do agree with Dave, this is not standard UVM way of doing things.

Link to comment
Share on other sites


This is a great way to deal with muli-channel type items, though (like 256 for a mixer on a sound card). Also when you have programmable vip you can use a dynamic array to set the #channels for the vif and this code would appropriately deal with a multi-channel situation in the scoreboard. I think I'll re-write our yapp_router example for dealing with the channels this way.

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...