Jump to content
Roman Popov

Modules with optional (configurable) ports

Recommended Posts

Hello, I'm working on reusable primitives for synthesizable SystemC (like bus transactors, FIFOs, arithmetic units).  Sometimes I need to make some ports optional, for example "number of items" signal in FIFO:

struct async_fifo: public sc_module {
...
sc_out <sc_uint<BITS_FIFO_DEPTH> >  num_items; // optional port

What is the best known method to do this?

 

Macros do not work, because they do not allow to make instances with different configurations:

#ifdef EN_NUM_ITEMS
     sc_out <sc_uint<BITS_FIFO_DEPTH> >  num_items; // if EN_NUM_ITEMS is defined, all instances will have this port

Probably someone has an efficient solution using template specialization?  I have not figured it out how to do it without a lot of copy-paste code in specializations.

 

 

The solution I currently use is the dynamic allocation of ports in constructors, depending on template parameters:

sc_out <sc_uint<BITS_FIFO_DEPTH> >  *num_items; // pointer to port

SC_CTOR(async_fifo) {

if (en_num_items)  num_items = new sc_out<sc_uint<BITS_FIFO_DEPTH> > ("num_items");
else num_items = NULL;
}

The drawback is that you will always have those null pointers shown in IDE auto-completion assistance. 

Share this post


Link to post
Share on other sites

Dear Roman,

 

How about sc_vector?

IEEE 1666-2011 SystemC LRM Section 8.5

 

Greetings

Ralph

 

yes, sc_vector is a solution similar to port pointer.  You will still have hanging empty sc_vectors, the same as with null pointers. But yes, sc_vectors and pointers are possible solutions. 

 

Unfortunately, sc_vectors are not yet supported by SystemC synthesis tools.  At least by those that I've tried. 

Share this post


Link to post
Share on other sites

AFAIK, using ports with an "optional" port policy (SC_ZERO_OR_MORE_BOUND) is not well supported by synthesis tools either.
But you can try inheriting structs with the port declarations depending on some template parameters (entirely untested):

template<bool HasMorePorts = true>
struct async_fifo_optional_ports {
  sc_out<sc_uint<BITS_FIFO_DEPTH> > num_items;
protected:
  void drive_num_items(const sc_uint<BITS_FIFO_DEPTH>& v) {
    num_items->write(v);
  }
};

template<> struct async_fifo_optional_ports<false> {
protected:
  void drive_num_items(const sc_uint<BITS_FIFO_DEPTH>&) {
    /* empty */
  }
};


template< bool HasMorePorts >
SC_MODULE( async_fifo )
  , public async_fifo_optional_ports<HasMorePorts>
{
  // ...
};

hth,
  Philipp

Share this post


Link to post
Share on other sites

AFAIK, using ports with an "optional" port policy (SC_ZERO_OR_MORE_BOUND) is not well supported by synthesis tools either.

But you can try inheriting structs with the port declarations depending on some template parameters (entirely untested):

 

Thanks Philipp, I think it may work actually. Will reply back when I test it.

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

×