Jump to content

How can I implement SC_FORK JOIN_ANY /SC_FORK JOIN_NONE


KEVIN CHACKO

Recommended Posts

Read up on sc_spawn and sc_process_handle. Basically, you can do something like:

// Example of fork-join any
std::vector<sc_process_handle> process_handles;
process_handles.push_back( sc_spawn( [&](){ ... } ); //< repeat as needed
...
sc_event_or_list terminated_events;
for( auto& ph : process_handles ) {
    terminated_events |= ph.terminated_event();
}
wait( terminated_events ); //< wait for any process to exit
for( auto& ph : process_handles ) {
  ph.kill();
}
// Example of fork-join none
(void)spawn( [&](){ ... } ); //< repeat as needed
...

 

Link to comment
Share on other sites

Thank your for the help.

But when I try implementing the fork_join any solution, I get this error

invalid use of sc_(and|or)_event_list: list prematurely destroyed

I am using the fork join any in a run phase process of a uvm systemc driver. This issue is reported specifically for 40th agent i am running out of 65 agents. 

Is it because the size of the process handles or the terminated_event list getting exhausted

 

 

Link to comment
Share on other sites

2 hours ago, KEVIN CHACKO said:

But when I try implementing the fork_join any solution, I get this error

invalid use of sc_(and|or)_event_list: list prematurely destroyed

This is interesting, comment in source code says that it reports this error when event_list is destroyed, but some process is still waiting for it.

Can you provide a small reproducer (complete code example) showing how you use it?

Link to comment
Share on other sites

Sure

The code is fine for SC_JOIN all and SC_JOIN NONE implementation. And apparently this issue is there for every uvm_component I instantiate.

#include<systemc.h>
#include<uvm>

template <int TOP_DEPTH=10>
class top: public uvm::uvm_component{
public:


       void fun1() {
         cout<<"Current time is "<< sc_time_stamp() << endl;
     cout<< " =========== fun1========" << endl;
         wait(30,SC_NS);
         cout<<"Current time is "<< sc_time_stamp() << endl;
       }

       void fun2() {
         cout<<"Current time is "<< sc_time_stamp() << endl;
        cout<< " =========== fun2========" << endl;
       wait(20,SC_NS);
         cout<<"Current time is "<< sc_time_stamp() << endl;
       }

   void run_phase(uvm::uvm_phase& phase) {
     
             cout<< " run: before fork/join" << endl;

         /*SC_FORK
                         sc_spawn(sc_bind(&top::fun1, this)),
                         sc_spawn(sc_bind(&top::fun2, this))
             SC_JOIN*/

         /*void(sc_spawn(sc_bind(&top::fun1, this)));
           void(sc_spawn(sc_bind(&top::fun2, this)));*/


 

    
     std::vector<sc_process_handle> process_handles;
     process_handles.push_back(sc_spawn(sc_bind(&top::fun1, this)) );
     process_handles.push_back(sc_spawn(sc_bind(&top::fun2, this)) );
     sc_event_or_list terminated_events;
     for(std::vector<sc_process_handle>::iterator it = process_handles.begin(); it != process_handles.end(); ++it) {
       terminated_events |= (*it).terminated_event();
     }
     wait( terminated_events ); //< wait for any process to exit
     for(std::vector<sc_process_handle>::iterator it = process_handles.begin(); it != process_handles.end(); ++it) {
       (*it).kill();
       }


                 cout << "run: after fork/join" << endl;
                wait(40,SC_NS);
                cout<<"Current time is "<< sc_time_stamp() << endl;
        }


 top (uvm::uvm_component_name name="top") : uvm::uvm_component( name ) {

     }

};

 

int sc_main(int argc, char **argv) {

       top<15>* top_1;

       top_1 = new top<15>("top_1");


       uvm::run_test("");

      return 0;

}
 

Link to comment
Share on other sites

Ok, thanks a lot for example. 

I'm not using UVM myself and have no idea what it does. But it looks like UVM does not allow you to call wait() inside run_phase, because it terminates the thread immediately.

If you rewrite your code this way:

    void run_phase(uvm::uvm_phase& phase) {

        cout<< " run: before fork/join" << endl;
      
        //

        cout << "run: after fork/join" << endl;
        wait(40,SC_NS);
        cout<<"Current time is "<< sc_time_stamp() << endl;
    }

You will see that "Current time is.." won't get printed.  

And because thread is terminated,  event_list got destroyed and you see the error you see.

From my perspective it is UVM-SystemC bug, it should prevent you from calling wait() from run_phase, by reporting something like "wait() is not allowed inside run_phase". 

I suggest you to post the issue to UVM SystemC support forum (http://forums.accellera.org/forum/38-systemc-verification-uvm-systemc-scv/) and see if anyone of UVM-SystemC developers can help/comment.

 

If you put your code in a regular SC_THREAD you will see that everything works as expected .

 

 

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.

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