Flori_He Posted May 14, 2016 Report Share Posted May 14, 2016 Hello,I simply don't get why the process axi_run() doesn't get triggered a second time. Here are all relevant(hopefully) code snippets:template<class T, unsigned int BUSWIDTH>tlm::tlm_sync_enum adc_slave<T, BUSWIDTH>::nb_trans(tlm::tlm_generic_payload& gp, tlm::tlm_phase& ph, sc_time& t) { assert(ph==tlm::BEGIN_REQ || ph==amba::BEGIN_DATA || ph==amba::BEGIN_DATA); if(ph==tlm::BEGIN_REQ) { sl_ph = tlm::END_REQ; sl_ev1.notify(SC_ZERO_TIME); wait(sl_ev2); sl_ph = tlm::BEGIN_RESP; sl_gp = &gp; if(gp.is_read()) { cout<<"notifying sl_ev1"<<endl; sl_ev1.notify(SC_ZERO_TIME); wait(sl_ev2); cout<<"waited for sl_ev2"<<endl; return tlm::TLM_ACCEPTED; } else .... }}...template<class T, unsigned int BUSWIDTH>void adc_slave<T, BUSWIDTH>::axi_run() { cout<<"entering..."<<endl; if(sl_ph==tlm::END_REQ) { cout<<"entering...end_req"<<endl; sl_gp->set_response_status(tlm::TLM_OK_RESPONSE); retVal = slave_sock->nb_transport_bw(*sl_gp, sl_ph, sl_t); assert(retVal==tlm::TLM_UPDATED); sl_ev2.notify(SC_ZERO_TIME); cout<<"leaving...end_req"<<endl; } else if(sl_ph==tlm::BEGIN_RESP) { cout<<"entering...end_resp"<<endl; ... }....} template<class T, unsigned int BUSWIDTH>adc_slave<T, BUSWIDTH>::adc_slave(...)... SC_THREAD(axi_run); dont_initialize(); sensitive<<sl_ev1;}...template<class T, unsigned int BUSWIDTH>class adc_slave: public sc_module {... public: ... sc_event sl_ev1, sl_ev2; .... }If I run my simulation (in which i call nb_transport with a read command), I get as an output:entering...entering...end_reqleaving...end_reqnotifying sl_ev1which means the process axi_run() doesn't get triggered a second time. So far there is no logical explanation for me, why this isn't happening. Does anyone have an idea?Thanks and greetings,Florian Quote Link to comment Share on other sites More sharing options...
apfitch Posted May 14, 2016 Report Share Posted May 14, 2016 Do you have an infinite loop in the SC_THREAD axi_run? - you need one, otherwise the thread will run once then return, regards Alan Quote Link to comment Share on other sites More sharing options...
dakupoto Posted May 15, 2016 Report Share Posted May 15, 2016 Hello, I simply don't get why the process axi_run() doesn't get triggered a second time. Here are all relevant(hopefully) code snippets: template<class T, unsigned int BUSWIDTH> tlm::tlm_sync_enum adc_slave<T, BUSWIDTH>::nb_trans(tlm::tlm_generic_payload& gp, tlm::tlm_phase& ph, sc_time& t) { assert(ph==tlm::BEGIN_REQ || ph==amba::BEGIN_DATA || ph==amba::BEGIN_DATA); if(ph==tlm::BEGIN_REQ) { sl_ph = tlm::END_REQ; sl_ev1.notify(SC_ZERO_TIME); wait(sl_ev2); sl_ph = tlm::BEGIN_RESP; sl_gp = &gp; if(gp.is_read()) { cout<<"notifying sl_ev1"<<endl; sl_ev1.notify(SC_ZERO_TIME); wait(sl_ev2); cout<<"waited for sl_ev2"<<endl; return tlm::TLM_ACCEPTED; } else .... } } ... template<class T, unsigned int BUSWIDTH> void adc_slave<T, BUSWIDTH>::axi_run() { cout<<"entering..."<<endl; if(sl_ph==tlm::END_REQ) { cout<<"entering...end_req"<<endl; sl_gp->set_response_status(tlm::TLM_OK_RESPONSE); retVal = slave_sock->nb_transport_bw(*sl_gp, sl_ph, sl_t); assert(retVal==tlm::TLM_UPDATED); sl_ev2.notify(SC_ZERO_TIME); cout<<"leaving...end_req"<<endl; } else if(sl_ph==tlm::BEGIN_RESP) { cout<<"entering...end_resp"<<endl; ... } .... } template<class T, unsigned int BUSWIDTH> adc_slave<T, BUSWIDTH>::adc_slave(...) ... SC_THREAD(axi_run); dont_initialize(); sensitive<<sl_ev1; } ... template<class T, unsigned int BUSWIDTH> class adc_slave: public sc_module { ... public: ... sc_event sl_ev1, sl_ev2; .... } If I run my simulation (in which i call nb_transport with a read command), I get as an output: entering... entering...end_req leaving...end_req notifying sl_ev1 which means the process axi_run() doesn't get triggered a second time. So far there is no logical explanation for me, why this isn't happening. Does anyone have an idea? Thanks and greetings, Florian Sir, 'wait-notify' pairs are tricky and work correctly if the programmer has been able to match each notify with the corresponding wait. Also, a few events might get lost. Why not use SC_THREADs with infinite loops in them, that will relieve the programmer from the error-prone task of matching 'waits' and 'notifys' -- the sensitivity list takes care of everything. Hope that helps. Quote Link to comment Share on other sites More sharing options...
Flori_He Posted May 16, 2016 Author Report Share Posted May 16, 2016 Hello Alan and dakupoto,nesting the code into an infinite loop, putting a wait(ev) at the beginning and deleting the static sensitivities solved the problem for me. Thanks very much for that. Nevertheless I still don't understand why the thread wasn't triggered a second time,Regards Florian Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted May 16, 2016 Report Share Posted May 16, 2016 Nevertheless I still don't understand why the thread wasn't triggered a second time, Unlike method processes, thread processes are triggered only once. With one exception of this rule: if you define reset signal for process (using reset_signal_is or async_reset_signal_is ), it will be restarted (triggered) on reset condition. Quote Link to comment Share on other sites More sharing options...
Flori_He Posted June 15, 2016 Author Report Share Posted June 15, 2016 Thanks for the info Roman! 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.