-2

I'm trying to accomplish this with HLS, not with "normal" C++, so most libraries (STL, boost, etc.) won't work as they can't be synthesized (manual memory management is not allowed). I think this should be possible with template metaprogramming, but I'm a little stuck.

I want to create an array of shift registers, each with a variable depth. I have N inputs, and I want to create N shift registers, with depths 1 to N, where N is known at compile time. My shift register class basically looks like

template<int DEPTH> class shift_register{ int registers[DEPTH]; ... }; 

I tried following this and adapting it: Programmatically create static arrays at compile time in C++ , however, the issue is with the last line. Each templated shift register is going to be a different type, and so can't be put together in an array. But I do need an array, as there wouldn't be a way to access each shift register.

Any help would be appreciated!

17
  • 3
    Sounds like an x/y-problem to me. Explain what "HLS" is and what you want to accomplish (not how). Up to now you said nothing but showed a trivial class containing an array. Commented Nov 12, 2018 at 1:28
  • 1
    yes, but what you showed is basically std::array<> so why not use that? Commented Nov 12, 2018 at 1:41
  • 1
    You can't have an array of elements which types are different from another. Commented Nov 12, 2018 at 1:46
  • 1
    You introduced a term "HLS" which you didn't explain and now you want to add "what needs to happen is that delays need to be added" some mysterious delays ... you aren't making any sense. Commented Nov 12, 2018 at 1:47
  • 2
    So "array" means packed buffer of uniform type that can be accessed by runtime index. I have no idea what subset of this you need, but apparently you don't want uniform types. We cannot solve a problem without aidea what the problem is. Commented Nov 12, 2018 at 4:03

3 Answers 3

0

Just to clarify, my problem was the following: generate N shift_registers, templated from 1 to N, where N is a compile time constant.

For example, if I had N=4, I could easily write this as:

shift_register<1> sr1; shift_register<2> sr2; shift_register<3> sr3; shift_register<4> sr4; 

But this wouldn't be easy to change, if I wanted a different value for N in the future.

I ended up using the preprocessor and took the solution from here: How do I write a recursive for-loop "repeat" macro to generate C code with the CPP preprocessor?

I used the macros from that solution like this:

#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define BODY(i) shift_register<i> CAT(sr,i) REPEAT_ADD_ONE(BODY, N, 1); 

And then something similar to that in order to access the shift registers, in a sort of array fashion.

This let me achieve the compile time generation that I was looking for, and get the array type access I needed.

Sign up to request clarification or add additional context in comments.

1 Comment

Does my solution help you?
0

Your question was somewhat difficult to understand but I'll do my best...

template <typename ... Args> constexpr auto make_array(Args && ... pArgs) { using type = std::common_type_t<std::decay_t<Args>...>; return std::array<type, sizeof...(Args)>{ (type)pArgs ... }; } 

Then use it like this:

auto constexpr var_array_of_arrays = std::make_tuple ( make_array(1, 2, 3, 3), make_array(2, 3, 4), make_array(1, 2, 3 ,4 ,3, 5) ); 

To get the M'th element you access it like this, n has to actually be a compile-time constant:

std::get<M>(var_array_of_arrays); 

To access the Nth element in the Mth array:

auto constexpr value = std::get<M>(var_array_of_arrays)[N] 

An to improve the interface:

template <size_t M, size_t N, typename T > constexpr decltype(auto) get_element(T && pInput) { return std::get<M>(std::forward<T>(pInput))[N]; } 

Used like this:

auto constexpr element0_1 = get_element<0, 1>(var_array_of_arrays); 

This will allow you to use an array of variable length arrays, or atleast something that behaves like that and is identical to that in memory. A full example is here: Online compiler

Comments

0

Whenever I hear "compile time number sequence" I think std::index_sequence

namespace detail { template <typename> struct shift_registers; template <std::size_t ... Is> // 0, 1, ... N-1 struct shift_registers<std::index_sequence<Is...> > { using type = std::tuple<shift_register<Is + 1>...>; }; template <typename T> using shift_registers_t = typename shift_registers<T>::type } template <std::size_t N> using shift_registers = detail::shift_registers_t<std::make_index_sequence<N>>; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.