Jump to content

Problem. num_available() method. Please help


Recommended Posts

Hi everybody.
I'm try to develop some project and met with problem.

My project is very simple: 2 Blocks has not duplex connection. (Block1 -> Block2). Block1 generating some data and send it to Block2. In fact, in behavioral code block2 have line

while(in_port_1009->num_available());
{
   // do something
}

i.e. he should wait some data in buffer. But I'm wrote some dbg line to check: wait my block some data or not.

while(in_port_1009->num_available());
{
       cout << sc_time_stamp() << " Im insinde obj 1: "<< endl;
        //Do something
};

This is code of Block1 (tranciever)

void process_thread()
{
	int res = 0;

	data_1004to1009 outMessage1004;

	while(true)
	{
		res = gen_data();

		itoa(res, outMessage1004.data, 10);
                wait(7, SC_NS);	// <- block2 go inside to the loop, when I'm do this line, //i.e. data not sended yet	
		out_port_1004->write(outMessage1004);
           
		}
	}

You can ask me why I'm use classes like a type of data for links. Answer: this is conditions of project.
Please, someone, help me ASAP.


Here attached  code:

 

main.cpp

#include <iostream>
#include <fstream>
using namespace std;



class data_1004to1009
{
public:
   char data[8];

   data_1004to1009()
   {
		memset(data, 0, sizeof(data));		
   }

   inline friend ostream& operator << ( ostream& os,  data_1004to1009_t const & v )
   {
       os << "(" << v.data << "," << std::boolalpha << "," << v.data << ")";
       return os;
   }
};

#include "peObj0.h"
#include "peObj1.h"

int sc_main(int argc, char* argv[])
{
	peObj0 peObj0Component("peObj0");
	peObj1 peObj1Component("peObj1");
	
	sc_fifo<data_1004to1009_t> fifoBufferPort1004toPort1009(1);
	peObj1Component.in_port_1009(fifoBufferPort1004toPort1009);
	peObj0Component.out_port_1004(fifoBufferPort1004toPort1009);

	sc_start(150, SC_NS);
	sc_stop();
	
	getchar();
	return 0;

}

pe0Obj.h

#include <iostream>
#include <systemc.h>

SC_MODULE(peObj0)
{
	
	//Ports declaration
	sc_port<sc_fifo_out_if<data_1004to1009> > 	out_port_1004;
	
	void process_thread()
	{
		int res = 0;

		data_1004to1009 outMessage1004;

		while(true)
		{						
			res = rand()%10;

			out_busy.write(0);
			itoa(res, outMessage1004.data, 10);		

			wait(7, SC_NS);
			
			out_port_1004->write(outMessage1004);
		}
	}

	
	SC_CTOR(peObj0)
	{	
		SC_THREAD(process_thread);
	};

};

peObj1.h
 

#include <iostream>
#include <systemc.h>

SC_MODULE(peObj1)
{
	sc_port<sc_fifo_in_if<data_1004to1009> > 		in_port_1009;
		
	void process_thread()
	{
		int in_dataValue1009 = 0;
		int res = 0;

		data_1004to1009 inMessage1009;		

		while(true)
		{
			out_busy.write(0);
			out_working.write(0);

			while(in_port_1009->num_available());
			{
				cout << sc_time_stamp() << " Im insinde obj 1: "<< endl;			
				in_port_1009->read(inMessage1009);
                                 in_dataValue1009   = atoi(inMessage1009.data);
				wait(6, SC_NS);
				cout << sc_time_stamp() << " peObj1 recieved data: "<< in_dataValue1009 << endl;
			}
		}
	}

	
	SC_CTOR(peObj1)
	{		
		SC_THREAD(process_thread);
	};

};

 

I HAVE TROUBLE WITH FILE UPLOADING. SORRY
 


 

Link to comment
Share on other sites

Hi, 

 

  you don't need the test for num_available(). If you change your reading code to

 

 

    void process_thread()
    {
        int in_dataValue1009 = 0;
        int res = 0;

        data_1004to1009 inMessage1009;        

        while(true)
        {
            out_busy.write(0);
            out_working.write(0);
            cout << sc_time_stamp() << " Im insinde obj 1: "<< endl;            
            in_port_1009->read(inMessage1009);
            in_dataValue1009 = atoi(inMessage1009.data);
            wait(6, SC_NS);
            cout << sc_time_stamp() << " peObj1 recieved data: "<< in_dataValue1009 << endl;
        }
    }

 

it should work fine. That's because read() is a blocking method - it suspends the SC_THREAD process when the fifo is empty.

I believe the problem with your original code is that if the fifo is empty, the receiver process never suspends, so the transmitter process gets no chance to run.

 

regards

Alan

Link to comment
Share on other sites

Thanks. But what I'm need to do, for example, if I'm will be have more that one input port.
for example
 

#include <iostream>
#include <systemc.h>

SC_MODULE(peObj1)
{
	sc_port<sc_fifo_in_if<data_1004to1009> > 		in_port_1009;
        sc_port<sc_fifo_in_if<data_1004to1009> > 		in_port_1008;
		
	void process_thread()
	{
		int in_dataValue1009 = 0;
		int res = 0;

		data_1004to1009 inMessage1009;		

		while(true)
		{
			while(in_port_1009->num_available() && in_port_10098->num_available()  )
			{
				cout << sc_time_stamp() << " Im insinde obj 1: "<< endl;			
				in_port_1009->read(inMessage1009);
                                 in_dataValue1009   = atoi(inMessage1009.data);
				wait(6, SC_NS);
				cout << sc_time_stamp() << " peObj1 recieved data: "<< in_dataValue1009 << endl;
			}
		}
	}

	
	SC_CTOR(peObj1)
	{		
		SC_THREAD(process_thread);
	};

};

One nuance of my block, that behavioral code must be executed only when block will have data at all ports. How to realise this synch point correctly?

Link to comment
Share on other sites

There's probably a better way (well, there's definitely a better way :-) ) but a quick hack would be to add

 

 

wait(SC_ZERO_TIME);

 

in front of the test for num_available(). That will ensure you don't get stuck in an infinite loop.

 

The other way (less hacky) would be to use the data_written_event() of the fifo channel, and trigger from an "and" of the data_written_events(), e.g.

 

 

wait (in_port_1009->data_written_event() & in_port_10098->data_written_event());

I haven't tested either of these, so YMMV,

 

regards

Alan

Link to comment
Share on other sites

The other way (less hacky) would be to use the data_written_event() of the fifo channel, and trigger from an "and" of the data_written_events(), e.g.

wait (in_port_1009->data_written_event() & in_port_10098->data_written_event());

 

 

Just a quick addition: In case the FIFOs do not receive their values symmetrically, you should wait for a data_written_event on any of the incoming FIFOs, in case of any FIFO being empty (i.e. after the loop).  This can be done by using an or-expression on the ports:

 

wait (in_port_1009->data_written_event() | in_port_10098->data_written_event()); // | instead of &

If you want to avoid some unnecessary wakeups, you can optimize this by using an explicit sc_event_and_list (here, an and is needed again):

 

sc_event_and_list written_events; // requires 2.3.0
if( !in_port_1009->num_available() )
    written_events &= in_port_1009->data_written_event();
if( !in_port_10098->num_available() )
    written_events &= in_port_10098->data_written_event();
wait( written_events );

 

 

Greetings from Oldenburg,

  Philipp

Link to comment
Share on other sites

Aptfich,
before establishing of this topic, I too felt that wait(SC_ZERO_TIME) construction will helps, but no. wait(SC_ZERO_TIME) construction will defer execution of code in the end of delta cycle.
Philipp already explained why your second proposal too does not work :)

This is too bad decision. Actually, my behavioral code should wake up only when he will has data in all buffers.

Link to comment
Share on other sites

Hi Ips,

   Philipp did not say my code would not work - he said it would not work if data in the fifos does not arrive symmetrically. My code assumed that the data arrived (in the case of two fifos) in pairs e.g.

 

fifo1 fifo2

  (trigger)

fifo1 fifo2

  (trigger)

fifo1 fifo2

  (trigger)

 

But note that with the event & the events do *not* have to happen simultaneously, and & operator waits until the anded events have occurred in any order.

 

 

What Philipp was saying is that maybe the data in your fifos arrives in some unknown order, e.g.

 

fifo1

fifo1

        fifo2

fifo1

        fifo2

        fifo2

        fifo2

 

in which case you need an or of events (either fifo needs to wake up the process, and then test if data is available in both fifos).

 

regards

Alan

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