Jump to content
Sign in to follow this  
socEE

Passing pointers through sc_signal and sc_port

Recommended Posts

Hello all,

I'm trying to build a model of an image processing system using systemC 2.2.0. Initially I'd like to pass images to each processing block using pointers so the simulation runs fast as the images will be large. Later the plan is to model data transfers between blocks more precisely.

I tried a simple program with two blocks communicating using two port types. One uses sc_bv<N> and the other uses a pointer to a struct. The sender writes to the output N times on both ports and the receiver reacts to the input ports and prints the result. Everything compiles okay but the program drops half of the pointers and keeps all the bit vectors.

I'm running this on Fedora 17 with gcc. All the test cases in /examples pass.

Compiled with 'clang++ main.cpp block1.cpp block2.cpp types.cpp -lsystemc'

I'm wondering if my code is the correct way to achieve what I'm trying to do. All the examples I see make copies through ports but this will be very inefficient.



typedef imageData * imageType;
typedef sc_bv<10> pixelType;


int sc_main(int argc, char * argv[])
{
 block1 sender("Sender");
 block2 receiver("Receiver");

 sc_signal<pixelType> pixel_chanel;
 sc_signal<imageType> image_channel;

 sender.p_data_out(pixel_chanel);
 sender.i_data_out(image_channel);

 receiver.p_data_in(pixel_chanel);	// Gets all of the data
 receiver.i_data_in(image_channel); // Gets half of the data

 sc_start(4,SC_US);
 return 0;
}


testcase.zip

Share this post


Link to post
Share on other sites

Hi,

the sc_signal class is designed to trigger sensitive processes when there is a change in value on the data it transfers. In your case that is a change in value *of the pointer* which is quite weird.

I would suggest using sc_fifo to communicate the data, using blocking reads and writes.

If you must use signals, use sc_buffer instead, as this creates an event on every write to the sc_buffer channel,

regards

Alan

Share this post


Link to post
Share on other sites

After some debugging with DDD, it seems this behavior is caused by the following code:

sc_signal.h

sc_signal<T>::write( const T& value_ )
{
   sc_object* writer = sc_get_curr_simcontext()->get_current_writer();
   if( m_writer == 0 ) {
    m_writer = writer;
   } else if( m_writer != writer ) {
    sc_signal_invalid_writer( this, m_writer, writer );
   }

   m_new_val = value_;
   if( !( m_new_val == m_cur_val ) ) {
    request_update();
   }
}

In my testcase the image memory is freed when the receiver method runs. This caused malloc to occasionally return the same pointer as before so the code above detected no change on the port and didn't schedule an event. Coming from Verilog, this makes sense for modeling hardware but not for mimicking a function call. Is there better way to do this?

Share this post


Link to post
Share on other sites

Hi,

the sc_signal class is designed to trigger sensitive processes when there is a change in value on the data it transfers. In your case that is a change in value *of the pointer* which is quite weird.

I would suggest using sc_fifo to communicate the data, using blocking reads and writes.

If you must use signals, use sc_buffer instead, as this creates an event on every write to the sc_buffer channel,

regards

Alan

Thanks for the response. I'll look into sc_fifo and sc_buffer.

Share this post


Link to post
Share on other sites

Another option would be to create a wrapper class that contained the pointer. Then you could write your own compare operator that examined the pointed to objects rather than the pointer. Overload operator== and operator= plus operator<<(ostream&,const WRAPPER&,char*)

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
Sign in to follow this  

×