Jump to content

SC_METHOD Dynamic Sensititivity Modification


Recommended Posts

Is is possible to modify an sc_method_process's dynamic sensitivity from outside the method itself?

While I can call next_trigger when the method is running, it would be preferable to add event sensitivity from another method/thread.

 

If not, one work workaround I came up with is the following:

sc_core::sc_event_or_list dynamic_sensitivity;
sc_core::sc_event sensitivity_change_event;

SC_METHOD(Change_Me_Method);
sensitive << sensitivity_change_event;

SC_THREAD(Changer_Thread);

void Change_Me_Method(){
  if(!sensitivity_change_event.triggered()){
	//Do stuff
  }
  next_trigger(dynamic_sensitivity | sensitivity_change_event);
}

sc_core::sc_event new_event;
void Changer_Thread(){
  dynamic_sensitivity |= new_event;
  sensitivity_change_event.notify();
}

Wondering if there is a cleaner solution.

Link to comment
Share on other sites

Basically there are other ways if you have a process handle. But for this you need to get a emthod handle. To do this you have 2 options:

  • You don't use SC_METHOD rather use sc_spawn directly (my _handle is a the part of you rmodule:
    sc_core::sc_spawn_options opt; 
    opt.dont_initialize();
    opt.spawn_method();
    my_handle = sc_core::sc_spawn(func, name,  &opt);
    this->sensitive << my_handle;
    this->sensitive_pos << my_handle;

    (if you don't use satic sensitivity you can skipe the last 2 liens). Using the handle you can change the sensitivity:
     

    reinterpret_cast<sc_method_process*>(my_handle.get_process_object())->next_trigger( sensitivity_change_event );

     

  • The other option is to retrieve the process handle upon the first invocation of your method using 'reinterpret_cast<sc_method_handle>(sc_get_current_process_handle()), store it in your module and then call next_trigger for it.

But I'm not sure it this is cleaner...

Link to comment
Share on other sites

20 hours ago, sheridp@umich.edu said:

This is exactly what I want to do, but next_trigger(sc_event_or_list&) is protected within sc_method_process.

... and sc_method_process is a non-standard class, which even is incomplete on the model side when including <systemc(.h)>. So I would not call this clean.

Regarding your original solution, it is important to note that you are not supposed to change an sc_event_list object while processes are sensitive to it. In your case, it works because you trigger the process immediately, which then 're-reads' the event list right away and therefore updates the sensitivity without breaking the kernel state

What do you want to achieve that makes you want to do this?

/Philipp

Link to comment
Share on other sites

  • 1 month later...

Sorry for the delay, I just saw this reply.

My use case is in modeling a CPU (at a pretty high, task level) using an SC_THREAD.  What the CPU does is cycle through its list of tasks which involves sending and receiving messages to other components (let's call it slaveA & slaveB).  However, if the CPU makes it through its whole list of tasks and has accomplished no useful work (e.g. it is polling slaves A & B, finding them not ready), then I need the CPU to sleep until either is ready. This is to help speed up the simulation (each cycle through the tasks involves multiple wait statements for small time increments if there's no useful work to do--I could just accumulate the time in loose fashion, but there are other reasons not to).

Rather than having to know apriori about slaveA and slaveB's wakeup events, I have a pointer to slaveA's event returned in the message after a call to b_transport.  Originally, I had collected these events in an sc_event_or_list, and if the CPU made i through its list of tasks without accomplishing work, it would wait on them.  However, I realized that if, while checking slaveB, slaveA notified its wakeup event, I would miss it and the CPU would wait when it should go back and check slaveA again, and might even deadlock if nothing wakes the CPU up after that.

Instead, what I wanted to do was have a method that would set a flag to tell the CPU to keep cycling.  If, after polling slaveA and finding it was busy, I would modify the method's sensitivity to include the event returned by slaveA.  Because next_trigger is a protected method, however, I cannot access it from withing the sc_thread of the CPU.

What I settled on was similar to this, but instead of modifying a single method's sensitivity, I spawn new instances of the flag-setting method immediately after I receive the event pointer (before yielding so that I cannot miss slaveA's notification).

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