Jump to content

Process doesn't get triggered


Flori_He

Recommended Posts

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


 

Link to post
Share on other sites

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.

Link to post
Share on other sites

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

Link to post
Share on other sites

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.

Link to post
Share on other sites
  • 5 weeks later...

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...