Jump to content
Moberg

Use event to communicate between modules

Recommended Posts

Two modules, an input Generator and a Controller.

The Generator sends a signal to increase a value in the Controller. The controller contains a loop where it checks if this value is > 0 and in that case do some stuf and reset it to zero.;

How should I connect these two modules? Sending an event seemed most intuitional, but it doesnt look like the standard way to do this.

I also read about semaphore but I'm not sure how to connect them. (I also want a monitor module to be able to print the value at some points (probably when it is reset))

Share this post


Link to post
Share on other sites

The normal way to connect modules is with ports (sc_port<IF> or sc_export<IF>) and channels. The primitive sc_signal<T> channel is probably what you want. For your purposes, you might want to use the simplified ports sc_in<T> and sc_out<T>, which are partial specializations on the sc_signal_in_if<T> and sc_signal_inout_if<T> interfaces respectively. This will allow you to wait on the default_event() method in your controller. Because the behavior of sc_signal requires only one writer, you have two choices. Either send a signal back (e.g. sc_buffer<bool> done) or if you guarantee writing won't happen in the same delta cycle, or you can change the policy.

Share this post


Link to post
Share on other sites

I'm not sure what to do, really ^^'

I'm not familiar with sc_buffer nor default_event().

I have this code right now. But in this way I can't react to two ones (1) coming in serie, because there has been no change on the input.

Testbench:

int sc_main(int argc, char **argv)
{
 sc_time sim_time(atof(argv[1]), SC_SEC);

 char *infile = argv[2];

 sc_signal<bool> sig;



 // create modules
 Generator generator("Generator", infile);

 Controller controller("Controller");

 // connect channels to ports
 generator(sig);
 controller(sig);
}

(stimuli) Generator:

SC_MODULE(Generator) {
 sc_out<bool> sensor;
 [...]
}


Generator::Generator(sc_module_name name, char *datafile)
: sc_module(name)
{
 in = new ifstream(datafile); // open input file (it is a file of ones and zeroes, a 1 indicating the sensor getting a new registration)
 SC_THREAD(generate_thread);
}

void Generator::generate_thread()
{
 for (;
 {
bool sens;
wait(1,SC_SEC); // generate new inputs every second
*in >> sens; // read from file
sensor = sens;
 }
}

(DUT) Controller:


SC_MODULE(Controller) {
 // input ports
 sc_in<bool> sensor;
 [...]

 //internal variables
 int value;

 //method
 void increase();

 // thread
 void controller();

 SC_CTOR(Lights)
 : value(0)

 {
SC_THREAD(controller);
sensitive << sensor;


SC_METHOD(increase);
sensitive << sensor;
dont_initialize();
 }
}


void Controller::controller() {
 while(true) {
while(value == 0)
  wait(); //this could/should wait for an event trigger fired by increase() instead.
if(value > 0)
{
  value = 0;
  wait(20, SC_SEC);
}
Some_Other_Stuff();
 }
}

void Controller::increase(){
 //if(sensor == 1)
 ++value;
}

As you see, instead of this signal I would like to trigger the method increase from another module. But I am not sure how to do this. I could let Generator send pulses. But it doesn't feel right.

All help is muchly appreciated.

Share this post


Link to post
Share on other sites

1. Change the signal to an sc_buffer (triggers an event upon every write):

sc_buffer<bool> sig;

2. Add an event to the controller, wait for it in controller thread, notify it from increase method

sc_event sensor_ev;
// ...
void Controller::controller() {
 while(true) {
while(value == 0)
  //  wait(); //this could/should wait for an event trigger fired by increase() instead.
	wait( sensor_ev );

if(value > 0) {
  value = 0;
  wait(20, SC_SEC);
}
Some_Other_Stuff();
 }
}

void Controller::increase(){
 //if(sensor == 1) {
 ++value;
 sensor_ev.notify( SC_ZERO_TIME );
 // }
}

Something like this? It's not clear, if the actual "value" is important. If it is not, you can only use the event for internal synchronisation.

Greetings from Oldenburg,

Philipp

Share this post


Link to post
Share on other sites

1. Change the signal to an sc_buffer (triggers an event upon every write):

sc_buffer<bool> sig;

Thanks this looks like the right stuff. I will try it in a while!

Should I use sig.write(true) or is it equal to normal assignment, i.e. sig = true:

Share this post


Link to post
Share on other sites

For the signal class, there is an overloaded operator= which calls write(), so you can do either.

Some people find it clearer to use write() so that you can tell that you are assigning to a special class, rather than a plain C variable. In other words it is a matter of style,

regards

Alan

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

×