Home > Software design >  How to dynamically create templated classes with compile-time information?
How to dynamically create templated classes with compile-time information?

Time:09-09

I am working on a small design with SystemC for a systolic array. For that I have implemented a templated shift register class where the data type and the delay are the templates. For every row of the array I need to attach a shift register with a different delay, e.g. the first row has no delay at all, the second one has one cylce delay, the third one has two cycles etc. For this I have constructed a loop inside the constructor that initializes the shift registers. The constructor then looks like this:

template<unsigned int HEIGHT, unsigned int WIDTH>
class SystolicArray : public sc_module{
  sc_module shift_registers[HEIGHT];

  SC_CTOR(SystolicArray){
    for(int h = 1; h < HEIGHT; h  ){
      shift_registers[h-1] = new ShiftRegister<type, h>
      //Do connections here...
    }
  }
};

Now the problem I am facing is that the compiler complains that I can't use h here in the way I did (# Error: systolic_array.h(61): error: the value of ‘h’ is not usable in a constant expression), and I do understand why that is the case. But all the information I need to construct this thing is available at compile time since it is all derived from the HEIGHT and WIDTH templates of the array. Is there a smarter way to do this than what I have tried here? I am working with C 11 and can only use the synthesizable subset of SystemC.

CodePudding user response:

You basically want "run this code with different values of h at compile time." Perfect for a template. You can do it with a pair of overloads like this:

private:
  template<int h>
  void init(std::integral_constant<int, h>) {
    shift_registers[h-1] = new ShiftRegister<type, h>;
    // Do connections here...

    // Next iteration
    init(std::integral_constant<int, h 1>{});
  }

  void init(std::integral_constant<int, H>) {
    // end when h==H
  }
public:
  SC_CTOR(SystolicArray){
    init(std::integral_constant<int, 1>{});
  }

With some precautions or possibly written some other way if H can equal 0.

CodePudding user response:

C 14 has std::index_sequence (which can be reimplemented in C 11)

so, with delagating constructor, it becomes:

SC_CTOR(SystolicArray) : SC_CTOR(SystolicArray, std::make_index_sequence<HEIGHT>{})
{}

template <std::size_t... Is>
SC_CTOR(SystolicArray, std::index_sequence<Is...>) :
    shift_registers{new ShiftRegister<type, h   1>...}
{
    // ...
}
  • Related