Jump to content

Segmentation fault whe using delayed sc_vector initialization


Fernando M

Recommended Posts

I am trying to code a very generic module that takes the number of elements of a sc_vector of sc_in from an argument. This module looks like:

 

transformation_arbiter.h

using namespace sc_core;
using namespace sc_dt;

class transformation_arbiter : public sc_module
{
public:
   sc_in<bool> clk;
   sc_vector< sc_in<bool> > enable_in;
   .
   .
   .
private:            
   unsigned pre_rep;

public:
   SC_HAS_PROCESS( transformation_arbiter );
   transformation_arbiter( sc_module_name trans_arbiter, unsigned ext_pre_rep ):
   sc_module( trans_arbiter ), pre_rep( ext_pre_rep ),
   enable_in( "enable_in" )
   {
      SC_THREAD( arbitrate );
      sensitive << clk;      
   }
   void arbitrate()
   {
      enable_in.init( pre_rep );
      .
      .
      .
   }

Then I am instantiating this module, along with a sc_vector of another module (request_generator.cpp) in a top module (top.cpp):

 

request_generator.h

.
.
.
using namespace sc_core;              
using namespace sc_dt;                
                                      
class req_generator : public sc_module
{                                     
public:                               
   //ports:                           
   sc_in_clk clk;                     
   sc_out<bool> enable_out;           
.
.
.

top.h

#include "trans_arbiter.h"
#include "request_generator.h"
.
.
.
sc_signal<bool> signal[4];
sc_vector<req_generator> req_gen;
transformation_arbiter   trans_1_arb;
.
.
.

and top.cpp

#include top.h

top::top(sc_module_name sys_m): sc_module(top_m), 
                                trans_1_arb ( "trans_1_arb", 4 ),
                                req_gen( "req_gen", 4)
{
   .
   .
   .
   for ( auto i = 0; i < REQ_MODULES; ++i )                            
   {                                                                       
      trans_1_arb.enable_in[i].bind    ( signal[i] );
   }
   .
   .
   .
}

The problem is that this causes a segmentation fault in the bind instruction:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000412501 in sc_core::sc_vector<sc_core::sc_in<bool> >::operator[] (this=0x7fffffffcec0, i=0) at ./systemc-2.3.1/include/sysc/utils/sc_vector.h:384
384         { return *static_cast<element_type*>( base_type::at(i) ); }

If I don't use de delayed initialization of the sc_vector like this:

public:
   SC_HAS_PROCESS( transformation_arbiter );
   transformation_arbiter( sc_module_name trans_arbiter ):
   sc_module( trans_arbiter ), enable_in( "enable_in", 4)
   {
      SC_THREAD( arbitrate );
      sensitive << clk;      
   }
   void arbitrate()
   {
      .
      .
      .
   }

The code works, but then it is not generic anymore, since several instances of the module could have different number of ports, and not always 4.

 

I'd really appreciate any help on this issue.

 

Thanks,

   Fernando

Link to comment
Share on other sites

I'm not really sure, but I'd guess that because you're making an sc_vector of ports, you need to obey the rules for ports. In particular, ports can only be instantiated during elaboration - by calling init() during a process, I think you're creating ports after elaboration.

 

Can you try putting the call to init() into the before_end_of_elaboration() callback instead?

 

Actually I'm not even sure that will work, but I think that's the underlying problem, the ports haven't been created at the point you're trying to bind them,

 

Alan

Link to comment
Share on other sites

Hi.

 

I see two problems in your code:

 

a) in top.h:

sc_signal<bool> signal[4];

This will not work. You cannot use SystemC objects in a normal array. Use sc_vector instead.

 

B)

Your sc_vector is empty at the point where you try to bind its elements.

Basically, David is right. You are creating ports after the end of elaboration which is not allowed. But even worse: You try to use the elements before you create them. The thread starts after all constructors and elabiration has been finished.

You have to call init before you start using the vector, e.g. in the constructor. Moving the init to the before_end_of_elaboration callback is possible as well. But, you have to move the binding of the ports to that callback as well then.

 

Greetings

Ralph

Link to comment
Share on other sites

Why use arrays when you could use a vector instead?

 

C style arrays have some diadvantages compared to vectors. No boundary checks, no size attributes, ...

Hence, using a vector is preferred over arrays in my opinion.

 

Now to SystemC:

SystemC objects are not Copyable and many on them are not DefaultConstructable. Both of these properties are required for std::vector. this is why sc_vector has been invented.

 

In your case the array works because sc_signal is DefaultConstructable. But you cannot assign a name to the signals.

 

Finally, you could use the bind facilities of sc_vector instead of binding all the elements in a loop.

 

Greetings

 

Ralph

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