Jump to content

Recommended Posts

Hi all,

I want to understand more about simple_initiator_sọket and simple_target_socket. How is it working??

Suppose, "Model A 3 initiator" -->  <-- "3 target Model B"

Case 1:

//Model A
tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket[3];
  ...
// Model B
tlm_utils::simple_target_socket_tagged<ModelB>* target_socket[3];
  ...
//bind
  for(int i=0;i<3;i++){
    objA->initiator_socket[i]->bind(objB->target_socket[i]);
  }

Case 2:

//Model A
tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket1;
tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket2;
tlm_utils::simple_initiator_socket_tagged<ModelA>* initiator_socket3;
  ...
// Model B
tlm_utils::simple_target_socket_tagged<ModelB>* target_socket1;
tlm_utils::simple_target_socket_tagged<ModelB>* target_socket2;
tlm_utils::simple_target_socket_tagged<ModelB>* target_socket3;
  ...
//bind
objA->initiator_socket1->bind(objB->target_socket2)
objA->initiator_socket2->bind(objB->target_socket3)
objA->initiator_socket3->bind(objB->target_socket1)

 

Question 1: Is both above code is correct?                   

Question 2: In case 2,  I set "bind" between Model A and Model B (unordered declare, initiator_socket1 with target_socket2 ,..... ). Is it right?         

Thanks all.

Share this post


Link to post
Share on other sites

In case 1 you should use sc_core::sc_vector<..> instead of a plain array as you cannot call constructors for plain arrays (what sc_vector does). Given that objA and objB are pointers case 1 is ok and works also with the sc_vector.

Case 2 is fine as far as I see...

Best regards

Share this post


Link to post
Share on other sites

Just looked further: there is a typo in case 1. It should read

//bind
  for(int i=0;i<3;i++){
    objA->initiator_socket[i]->bind(*(objB->target_socket[i]));
  }

as you use an array of pointers. Again, sc_vector eases your life:

//Model A
sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<ModelA>> initiator_socket;
  ...
// Model B
sc_core::sc_vector<tlm_utils::simple_target_socket_tagged<ModelB>> target_socket;
  ...
//bind
  for(int i=0;i<3;i++){
    objA->initiator_socket[i].bind(objB->target_socket[i]);
  }
                     
    

The same applies to case 2:

//bind
objA->initiator_socket1->bind(*(objB->target_socket2));
objA->initiator_socket2->bind(*(objB->target_socket3));
objA->initiator_socket3->bind(*(objB->target_socket1));

Best regards

Share this post


Link to post
Share on other sites

I would suggest that those for-loops need a better bound and should be coded:

sc_assert( objA->initiator_socket.size() >= objB->target_socket.size() && objB->target_socket.size() > 0 );
for( int i=0;i<objA->initiator_socket.size(); ++i )
{
  objA->initiator_socket[i].bind(objB->target_socket[i]);
}

Coding rule: NEVER use a literal constant when a reasonable alternative is possible.

Even when "in a hurry", you will not be disappointed if you use this rule.

 

Share this post


Link to post
Share on other sites
4 hours ago, Eyck said:

Just looked further: there is a typo in case 1. It should read


//bind
  for(int i=0;i<3;i++){
    objA->initiator_socket[i]->bind(*(objB->target_socket[i]));
  }

as you use an array of pointers. Again, sc_vector eases your life:


//Model A
sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<ModelA>> initiator_socket;
  ...
// Model B
sc_core::sc_vector<tlm_utils::simple_target_socket_tagged<ModelB>> target_socket;
  ...
//bind
  for(int i=0;i<3;i++){
    objA->initiator_socket[i].bind(objB->target_socket[i]);
  }
                     
    

The same applies to case 2:


//bind
objA->initiator_socket1->bind(*(objB->target_socket2));
objA->initiator_socket2->bind(*(objB->target_socket3));
objA->initiator_socket3->bind(*(objB->target_socket1));

Best regards

Thank @Eyck @David Black

 

///Constructor 
for (unsigned int channel = 0 ; channel < NUM_CHANNEL ; channel++) {
    char socketName[100];
    sprintf(socketName,"initiator%d",channel);
    initiator_socket[channel] = new tlm_utils::simple_initiator_socket_tagged<ModelA>(socketName);
}
....

I want to use pointer to set name for each inittiator_socket[channel] (as above code I used "socketName" variable)

@Eyck Can you show me how to use sc_vector and set name for each inittiator_socket? 

Thanks all.

Share this post


Link to post
Share on other sites

I change 

simple_initiator_socket_tagged<Router>* initiator_socket[N_TARGETS];

to:

sc_vector< simple_initiator_socket_tagged<Router >* > initiator_socket;

but cannot.
Error    C2825    'T': must be a class or namespace when followed by '::'    ..\..\libs\systemc-2.3.2\src\sysc\utils\sc_vector.h    502    

Share this post


Link to post
Share on other sites

Hello @TRANG,

You probably need to change from this:

sc_vector< simple_initiator_socket_tagged<Router >* > initiator_socket;

to this:

sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;

And to understand the better use of sc_vector you can probably search and find many references on  using sc_vector in the forum or on stackoverflow such as these ones:

Hope these helps.

Regards,

Ameya Vikram Singh

Share this post


Link to post
Share on other sites
24 minutes ago, AmeyaVS said:

Hello @TRANG,

You probably need to change from this:


sc_vector< simple_initiator_socket_tagged<Router >* > initiator_socket;

to this:


sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;

And to understand the better use of sc_vector you can probably search and find many references on  using sc_vector in the forum or on stackoverflow such as these ones:

Hope these helps.

Regards,

Ameya Vikram Singh

Thanks @AmeyaVS

how to set base name for each initiator_socket?

Suppose, I have initiator_socket[4]. I only initialize initiator_socket as bellow code.

sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;
...
///
Router::Router():initiator_socket("initiator_socket",4)
{}

I can't set base name for each initiator_socket as my expected.

ex:   initiator_socket[0]   : " initiator_0_socket"

         initiator_socket [ 1]    : " initiator_1_socket"

         initiator_socket [ 2]    : " initiator_2_socket"

         initiator_socket [ 3]    : " initiator_3_socket"

Share this post


Link to post
Share on other sites

Hello @TRANG,

By using sc_vector the sockets would be named as follows:

initiator_socket[0]   : " initiator_socket_0"

initiator_socket [ 1]    : " initiator_socket_1"

initiator_socket [ 2]    : " initiator_socket_2"

initiator_socket [ 3]    : " initiator_socket_3"

or you can use something mentioned here in this answer to name the interfaces.

It will be better to use the default naming scheme as it would make it consistent across the SystemC simulation.

Hope it helps.

Regards,

Ameya Vikram Singh

Share this post


Link to post
Share on other sites
52 minutes ago, TRANG said:

I can't set base name for each initiator_socket as my expected.

ex:   initiator_socket[0]   : " initiator_0_socket"

         initiator_socket [ 1]    : " initiator_1_socket"

         initiator_socket [ 2]    : " initiator_2_socket"

         initiator_socket [ 3]    : " initiator_3_socket"

For this, you can use a custom creator, e.g. a lambda function in C++11.  For a tagged socket, you anyway need to specify the tag in the for the callbacks, so doing the registration in the creator saves you another loop in your code:

sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;
...
///
Router::Router():initiator_socket("initiator_socket",4,
  [this](const char* /*unused*/, size_t idx) {
    std::stringstream ss;
      ss << "initiator_" << idx << "_socket";
    auto * socket = new tlm_utils::simple_initiator_socket_tagged<Router >( ss.str().c_str() );
    //socket->register_invalidate_direct_mem_ptr( ..., idx );
    return socket;
  })

{}

 

Hope that helps,
  Philipp

Edited by Philipp A Hartmann

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×