KEVIN CHACKO Posted January 12, 2019 Report Share Posted January 12, 2019 How can i implement SC_FORK JOIN_ANY and SC_FORK JOIN_NONE in systemC which is analogous to systemverilog Quote Link to comment Share on other sites More sharing options...
David Black Posted January 12, 2019 Report Share Posted January 12, 2019 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 ... Roman Popov 1 Quote Link to comment Share on other sites More sharing options...
KEVIN CHACKO Posted January 16, 2019 Author Report Share Posted January 16, 2019 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 Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted January 16, 2019 Report Share Posted January 16, 2019 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? Quote Link to comment Share on other sites More sharing options...
KEVIN CHACKO Posted January 16, 2019 Author Report Share Posted January 16, 2019 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; } Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted January 16, 2019 Report Share Posted January 16, 2019 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 . Quote Link to comment Share on other sites More sharing options...
KEVIN CHACKO Posted January 17, 2019 Author Report Share Posted January 17, 2019 Yes I could see that it work fine with regular SC_THREAD. Thanks for the help though. 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.