Jump to content
Aaron Yang

SC_METHOD performance improvement discussion

Recommended Posts

Hey Guys, 

I am kinda new to this language so bear with me if question sounds naive.

I am building cycle accurate system C model. When I run performance profiler, some process triggered by clk consume a lot resources(clk is always running).

So I am looking for tricks to improve the performance:

Original code:

SC_METHOD(process_output);
sensitive << reset;
sensitive << clk.pos();
...
void fir::process_output()
{
    if (reset.read() == 0) {
		//reset sequence
    }
    else {
      	if(enable.read()) {
    		//normal operation
        }
    }
}

One way to avoid triggered the process every time clk toggles is that create a event:

void fir::enable_event()
{
	if (enable.read()) {
		enable_rise.notify();
	}
}
...
void fir::process_output()
{
    if (reset.read() == 0) {
		//reset seq
    }
    else
    {
		if (enable.read() == 0) {
			next_trigger(enable_rise);//Correct me if I am wrong, based on my understanding, next_trigger() overrides the static sensitivity list.
        }
   	   else {
   			next_trigger();
      		//normal op
       }
    }
}
		

 

The other way is to use .suspend() and .resume();

SC_THREAD(monitor_trig_event);
sensitive << reset << enable;
...
void fir::monitor_trig_event() {
	sc_spawn_options opt;
	opt.set_sensitivity(&clk.pos());
	sc_process_handle handle = sc_spawn(sc_bind(&fir::process_output, this), "run_fir", &opt);
	handle.suspend();
	while (1) {
		wait();
		if (!reset) reset();
		else {
			if (enable.read()) {
				handle.resume();
				break;
			}
			else if (enable.read() == 0) {
				handle.suspend();
			}
		}
	}

In this case, process output won't have next_trigger() statement anymore.

For those two methods above, which one is more recommended? Or is there any clean and straightforward way to implement the improvement?

 

Thank you all in advance.

Share this post


Link to post
Share on other sites

Are you only looking at disabling  process_output from getting triggered when reset is on? In that case, it is as simple as:

void fir::process_output()
{
   if (reset.read() == 0) {
      //reset sequence
      next_trigger(reset.pos());
   }
   else if (clk.read() == 0) {
      //Ignore the trigger just after reset is de-asserted and 
      //sync to next clock edge
      next_trigger(clk.pos());
      // Note: will work even if we comment out line above, due to static sensitivity
   }
   else {
      if(enable.read()) {
         //normal operation
      }
   }
}

But this may not really get you a significant improvement in itself. You may want to check what is going on in "normal operation" - and see if you can optimize that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×