kaushalyjain Posted May 13, 2014 Report Share Posted May 13, 2014 Hi, So I have a submodule having an array of boolean input ports. Now in the top module, I define an sc_vector of the submodule type. Also, I define an array of sc_vector signals to be bound to. Questions: Can I use an array of sc_vectors? Any conventions on using them? eg: can I write sc_vector < sc_signal <bool> > operand_vec[max_operands]; If no, then is there any work around for this? Also, I now need to assemble and bind these ports: The code below doesn't seem to work. Both the stack_cnt_vec and operand_vec are initialized properly. for(int i=0;i<max_operands;i++){ operand_vec[i].init(10); } for(int i=0; i<10; i++) { sc_assemble_vector( stack_cnt_vec, &StackController::operands[i]).bind( operand_vec[i] ); } Thanks a lot for your time. Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted May 13, 2014 Report Share Posted May 13, 2014 Before trying to answer your question, can you provide some more information? Why don't you use an sc_vector of boolean input ports instead of an array in your submodule? How do you want to wire up the top-level module signals with the submodule signals (indexwise)? Can you provide a stripped-down but compilable code example? (add comments for the missing parts) In general, it is possible to have both an array of sc_vectors as well as an sc_vector of sc_vectors. If you don't want to use a custom "creator function", you just need to take care of the proper initialisation yourself.sc_assemble_vector might not be of much help (depending on the intended topology).You can still do the binding manually in a nested loop over both dimensions, of course. /Philipp kaushalyjain 1 Quote Link to comment Share on other sites More sharing options...
kaushalyjain Posted May 13, 2014 Author Report Share Posted May 13, 2014 Thank you Philip for the prompt answer/suggestions: Appending my requirements through a sample code written/edited by you only (taken from OFFIS website): Desired topology: Each of the in[3] ports in the 4 submodules need to be bound with the corresponding in_vec[3] vector Hence, binding looks something like this module.in_vec_0[0:2] <bound to> sub_module.in[0:2] This is also shown in the code below in for loop commented out and works fine 1) So, in my design: my submodule has a multi-port (currently defined here as in[3] array) Now, if I define input ports as sc_vector (as seen in commented portion of submodule), how do I bind the vector of vectors? Could you please show with this example? 2) Also, is there a better way to bind these ports using sc_assemble_vector? #include "systemc.h" SC_MODULE( sub_module ) { sc_in <sc_uint <16> > > in[3]; SC_CTOR(sub_module) {} //possible alternative: but how do i bind this using sc_assemble_vector // sc_vector<sc_in<sc_uint <16> > > in; // SC_CTOR(sub_module):in(3) {} }; SC_MODULE( module ) { // vector of sub-modules sc_vector< sub_module > m_sub_vec; // vector of ports sc_vector < sc_in<sc_uint<16> > > in_vec[3]; module( sc_core::sc_module_name, unsigned n_sub ) : m_sub_vec( "sub_modules", n_sub ) // set name prefix, and create sub-modules // , in_vec() // use default constructor // , in_vec( "in_vec" ) // set name prefix { // delayed initialisation of port vector // here with default prefix sc_core::sc_gen_unique_name("vector") // bind ports of sub-modules -- sc_assemble_vector for(unsigned i=0;i<3;i++){ in_vec[i].init( n_sub ); cout << "Size of vector " << m_sub_vec.size()<<endl; //can I use sc_assemble_vector in this case? //sc_assemble_vector( m_sub_vec, &sub_module::in).bind( in_vec ); //the following element by element binding works, but is there a neater way? /* for(unsigned j=0;j<m_sub_vec.size();j++){ m_sub_vec[j].in[i](in_vec[i][j]); } */ } } }; int sc_main(int , char* []) { module m("dut", 4); std::vector<sc_object*> children = m.get_child_objects(); for (size_t i=0; i<children.size(); ++i ) cout << children[i]->name() << " - " << children[i]->kind() << endl; cout << "Program completed" << endl; return 0; } Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted May 13, 2014 Report Share Posted May 13, 2014 Yes, if you use an sc_vector in your sub-module //possible alternative: but how do i bind this using sc_assemble_vector sc_vector<sc_in<sc_uint <16> > > in; SC_CTOR(sub_module) :in("in",3) // note the required name prefix, naming objects is good style anyway {} and an sc_vector of sc_vectors for the top-level ports (or a flattened sc_vector and then use the iterator-based binding API), you can use sc_assemble_vector to bind the whole hierarchy in one call (outside of the loops): // vector of ports sc_vector<sc_vector < sc_in<sc_uint<16> > > > in_vec; // ... and in the constructor sc_assemble_vector( m_sub_vec, &sub_module::in).bind( in_vec );If you want it even more neatly, use a "custom creator" to initialize the two-dimensional port vector: // creator function (beware of the hard-coded size 3) static sc_vector<sc_in<sc_uint<16> > >* create_in_vector(const char* nm, size_t ) { return new sc_vector<sc_in<sc_uint<16> > >(nm,3); } // constructor - look, ma', no loops! module( sc_core::sc_module_name, unsigned n_sub ) : m_sub_vec( "sub_modules", n_sub ) // set name prefix, and create sub-modules , in_vec( "in_vec" ) // set name prefix, no init yet { in_vec.init(n_sub, create_in_vector); // use custom creator // push it even further: use a C++11 lambda as a creator // in_vec.init(n_sub // , [](const char* nm, size_t) // lambda function // { return new sc_vector<sc_in<sc_uint<16> > >(nm,3); } ); // do the binding sc_assemble_vector( m_sub_vec, &sub_module::in).bind( in_vec ); } Hope that helps, Philipp kaushalyjain 1 Quote Link to comment Share on other sites More sharing options...
kaushalyjain Posted May 13, 2014 Author Report Share Posted May 13, 2014 Thanks again Philip. That really helped. So, if we are using a sc_vector of sc_vectors, we compulsorily need to create a custom creator function/lambda function for initializing such sc_vector of sc_vectors ? A naive question, but where do we need custom creator functions in general? Also, do they have to be static (like in this case). Also, in the LRM, page 405 (8.5.5) the following example uses a custom creator function and does it using Boost bind. How is it different from this case? While using the custom creator function for initialization as in your answer, can we pass the arguments to the function (char* , size_t) ? I tried doing it but it threw an error. // Case 2: creator is a member function my_module* my_module_creator_func( const char* name, size_t i ) { return new my_module( name, "value_of_extra_arg" ); } Top(sc_module_name _name, int N) { // Initialize vector passing through constructor arguments to my_module // Case 1: construct and pass in a function object vector1.init(N, my_module_creator("value_of_extra_arg")); // Case 2: pass in a member function using Boost bind vector2.init(N, sc_bind( &M::my_module_creator_func, this, sc_unnamed::_1, sc_unnamed::_2 ) ); Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted May 14, 2014 Report Share Posted May 14, 2014 So, if we are using a sc_vector of sc_vectors, we compulsorily need to create a custom creator function/lambda function for initializing such sc_vector of sc_vectors ? No, you can also explicitly init() the sub-vectors in a loop, as you did before. A naive question, but where do we need custom creator functions in general? A creator function is only strictly needed if you are forced to call a custom constructor for the vector elements, e.g. with additional parameters. In the vector of vector case, this can be the size of the vector. Also, do they have to be static (like in this case). Also, in the LRM, page 405 (8.5.5) the following example uses a custom creator function and does it using Boost bind. How is it different from this case? You can pass any C++ entity that can be called with a signature (const char*, size_t) and returns a pointer of the correct vector member type. The sc_bind example is a convenient way to pass additional information to the creator. By binding a member function, you can for example access the members of the module within the creator. While using the custom creator function for initialization as in your answer, can we pass the arguments to the function (char* , size_t) ? I tried doing it but it threw an error. // Case 2: creator is a member function my_module* my_module_creator_func( const char* name, size_t i ) { return new my_module( name, "value_of_extra_arg" ); } Top(sc_module_name _name, int N) { // Initialize vector passing through constructor arguments to my_module // Case 1: construct and pass in a function object vector1.init(N, my_module_creator("value_of_extra_arg")); // Case 2: pass in a member function using Boost bind vector2.init(N, sc_bind( &M::my_module_creator_func, this, sc_unnamed::_1, sc_unnamed::_2 ) ); In both examples you have quoted after your question, you see the options to pass additional information to the creator. In case 1, it is an explicit constructor argument passed to the my_module_creator function object, in case 2, it's the this pointer, passed to sc_bind. With a C++ lambda, you can use the various "capturing" mechanisms. /Philipp kaushalyjain 1 Quote Link to comment Share on other sites More sharing options...
kaushalyjain Posted May 14, 2014 Author Report Share Posted May 14, 2014 That clarifies a lot of my doubts. Thank you again Philip. I realize that the best/quickest way to clarify doubts is indeed posting on the forum! Also really appreciate the veterans giving prompt replies Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.