Jump to content
YashJ

SystemC Program: Variable changing its value automatically

Recommended Posts

In my code the variable 'inter' is changing its value by itself whenever, it is read/assigned. Please help

 

void dff(){
  	cout<<"IN DFF"<<endl;
 	cout<<sc_time_stamp()<<endl;
  	wait(10,SC_NS);
 	cout<<sc_time_stamp()<<endl;
  
    
    
    while(true){
      wait();
      cout<<"\nIN = "<<in.read()<<"  TIME"  <<sc_time_stamp()<<endl;
      inter.write(in.read());
      cout<<"\nInter before wait= "<<inter.read()<<endl;
       wait(10,SC_NS);
      out.write(inter.read());
      cout<<"\nInter after wait= "<<inter.read()<<endl;
      cout<<"\nOUT = "<<out.read()<<"  TIME"  <<sc_time_stamp()<<endl;
      cout<<"\nIN when outed = "<<in.read()<<endl;
    }
    
    
  }
  

The Complete Code is at:  here

Please help. Once you run the progam, the value of inter 'before wait' and 'after wait' in the ouput.

Thanks in advance

Share this post


Link to post
Share on other sites

When reading the signal 'inter' right after writing  to it (line 25 of the referenced code) you read the current value and not the scheduled (new) value. Writes to signals (as part of methods or threads) are executed in the evaluation phase of the simulation kernel while the value is assigned during the update phase of the kernel (see also https://ptolemy.berkeley.edu/projects/embedded/research/hsc/class/ee249/lectures/l10-SystemC.pdf?46).

If you read a signal in the same evaluation phase you are writing to it, you will always get the current value, not the new (scheduled) value. If you have several assignments to the signal the last one will always win. I.e. lets assume you have a signale  and a thread like:

void thread(){
  sig.write(42);
  wait(0, SC_NS); // advance by 1 delta cycle
  sig.write(1);
  cout<<"Sig is "<<sig.read()<<std::endl;
  sig.write(2);
  cout<<"Sig is "<<sig.read()<<std::endl;
  sig.write(3);
  cout<<"Sig is "<<sig.read()<<std::endl;
  wait(SC_ZERO_TIME); // same as the last wait(), advance by 1 delta cycle
  cout<<"Sig is "<<sig.read()<<std::endl;
}

you will get the output:

Sig is 42
Sig is 42
Sig is 42
Sig is 3

because the update to sig will only happen during the wait() call.

I hope this answers your question.

Share this post


Link to post
Share on other sites

Hello @YashJ,

It is expected behavior.

Here is a brief explanation:

//...

// Find the inline comments:

while(true){
  wait(); //< Wait for default event sensitivty(static sensitive event!). In you case it is in.value_changed()
  cout<<"\nIN = "<<in.read()<<"  TIME"  <<sc_time_stamp()<<endl;
  inter.write(in.read()); //< Write to the inter signal -> which means schedule and event for updating the sc_signal.
  cout<<"\nInter before wait= "<<inter.read()<<endl;
  wait(10,SC_NS); //< Relinquish control to the SystemC scheduler -> perform evaluate and update phase for all event scheduled. (Change sensitivity to dynamic scheduled after 10 ns)
  out.write(inter.read()); //< inter has the new value assigned at 3 lines before this statement.
  cout<<"\nInter after wait= "<<inter.read()<<endl;
  cout<<"\nOUT = "<<out.read()<<"  TIME"  <<sc_time_stamp()<<endl;
  cout<<"\nIN when outed = "<<in.read()<<endl;
}
///....

Hope it helps.

Regards,
Ameya Vikram Singh

Share this post


Link to post
Share on other sites

Yes, SystemC is doing exactly what is supposed to do. Perfect behavior and standard reaction when you don't understand event driven simulators.

In Verilog/SystemVerilog, this behavior is called non-blocking assignment (NBA). In VHDL, this is the behavior of a signal.

 

 

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

×