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>...}
{
// ...
}