File indexing completed on 2025-06-20 01:53:07
0001 #ifndef DATAFORMATS_L1TPARTICLEFLOW_ENCODING_H
0002 #define DATAFORMATS_L1TPARTICLEFLOW_ENCODING_H
0003
0004 #include <cassert>
0005 #include <type_traits>
0006
0007 #include "DataFormats/L1TParticleFlow/interface/datatypes.h"
0008
0009 template <typename U, typename T>
0010 inline void pack_into_bits(U& u, unsigned int& start, const T& data) {
0011 const unsigned int w = T::width;
0012 u(start + w - 1, start) = data(w - 1, 0);
0013 start += w;
0014 }
0015
0016 template <typename U, typename T>
0017 inline void unpack_from_bits(const U& u, unsigned int& start, T& data) {
0018 const unsigned int w = T::width;
0019 data(w - 1, 0) = u(start + w - 1, start);
0020 start += w;
0021 }
0022
0023 template <typename U>
0024 inline void pack_bool_into_bits(U& u, unsigned int& start, bool data) {
0025 u[start++] = data;
0026 }
0027
0028 template <typename U>
0029 inline void unpack_bool_from_bits(const U& u, unsigned int& start, bool& data) {
0030 data = u[start++];
0031 }
0032
0033
0034
0035
0036
0037 enum class PackingStrategy { DEFAULT, BARREL, ENDCAP };
0038
0039
0040 template <typename T,
0041 int NB,
0042 PackingStrategy METHOD = PackingStrategy::DEFAULT,
0043 typename std::enable_if<METHOD == PackingStrategy::DEFAULT, int>::type = 0>
0044 inline auto unpack_helper(const ap_uint<NB>& data) {
0045 static_assert(T::BITWIDTH <= NB, "NB Type is too small for the object");
0046 return T::unpack(data);
0047 }
0048
0049
0050 template <typename T,
0051 int NB,
0052 PackingStrategy METHOD,
0053 typename std::enable_if<METHOD == PackingStrategy::BARREL, int>::type = 0>
0054 inline auto unpack_helper(const ap_uint<NB>& data) {
0055 static_assert(T::BITWIDTH_BARREL <= NB, "NB Type is too small for the object");
0056 return T::unpack_barrel(data);
0057 }
0058
0059
0060 template <typename T,
0061 int NB,
0062 PackingStrategy METHOD,
0063 typename std::enable_if<METHOD == PackingStrategy::ENDCAP, int>::type = 0>
0064 inline auto unpack_helper(const ap_uint<NB>& data) {
0065 static_assert(T::BITWIDTH_ENDCAP <= NB, "NB Type is too small for the object");
0066 return T::unpack_endcap(data);
0067 }
0068
0069
0070 template <typename T,
0071 int NB,
0072 PackingStrategy METHOD = PackingStrategy::DEFAULT,
0073 typename std::enable_if<METHOD == PackingStrategy::DEFAULT, int>::type = 0>
0074 inline auto unpack_slim_helper(const ap_uint<NB>& data) {
0075 static_assert(T::BITWIDTH_SLIM <= NB, "NB Type is too small for the object");
0076 return T::unpack(data);
0077 }
0078
0079
0080 template <typename T,
0081 int NB,
0082 PackingStrategy METHOD,
0083 typename std::enable_if<METHOD == PackingStrategy::BARREL, int>::type = 0>
0084 inline auto unpack_slim_helper(const ap_uint<NB>& data) {
0085 static_assert(T::BITWIDTH_BARREL_SLIM <= NB, "NB Type is too small for the object");
0086 return T::unpack_barrel(data);
0087 }
0088
0089
0090 template <typename T,
0091 int NB,
0092 PackingStrategy METHOD,
0093 typename std::enable_if<METHOD == PackingStrategy::ENDCAP, int>::type = 0>
0094 inline auto unpack_slim_helper(const ap_uint<NB>& data) {
0095 static_assert(T::BITWIDTH_ENDCAP_SLIM <= NB, "NB Type is too small for the object");
0096 return T::unpack_endcap(data);
0097 }
0098
0099
0100 template <typename T,
0101 int NB,
0102 PackingStrategy METHOD = PackingStrategy::DEFAULT,
0103 typename std::enable_if<METHOD == PackingStrategy::DEFAULT, int>::type = 0>
0104 inline auto pack_helper(const T& obj) {
0105 static_assert(T::BITWIDTH <= NB, "NB Type is too small for the object");
0106 return obj.pack();
0107 }
0108
0109
0110 template <typename T,
0111 int NB,
0112 PackingStrategy METHOD,
0113 typename std::enable_if<METHOD == PackingStrategy::BARREL, int>::type = 0>
0114 inline auto pack_helper(const T& obj) {
0115 static_assert(T::BITWIDTH_BARREL <= NB, "NB Type is too small for the object");
0116 return obj.pack_barrel();
0117 }
0118
0119
0120 template <typename T,
0121 int NB,
0122 PackingStrategy METHOD,
0123 typename std::enable_if<METHOD == PackingStrategy::ENDCAP, int>::type = 0>
0124 inline auto pack_helper(const T& obj) {
0125 static_assert(T::BITWIDTH_ENDCAP <= NB, "NB Type is too small for the object");
0126 return obj.pack_endcap();
0127 }
0128
0129
0130 template <typename T,
0131 int NB,
0132 PackingStrategy METHOD = PackingStrategy::DEFAULT,
0133 typename std::enable_if<METHOD == PackingStrategy::DEFAULT, int>::type = 0>
0134 inline auto pack_slim_helper(const T& obj) {
0135 static_assert(T::BITWIDTH_SLIM <= NB, "NB Type is too small for the object");
0136 return obj.pack_slim();
0137 }
0138
0139
0140 template <typename T,
0141 int NB,
0142 PackingStrategy METHOD,
0143 typename std::enable_if<METHOD == PackingStrategy::BARREL, int>::type = 0>
0144 inline auto pack_slim_helper(const T& obj) {
0145 static_assert(T::BITWIDTH_BARREL_SLIM <= NB, "NB Type is too small for the object");
0146 return obj.pack_barrel_slim();
0147 }
0148
0149
0150 template <typename T,
0151 int NB,
0152 PackingStrategy METHOD,
0153 typename std::enable_if<METHOD == PackingStrategy::ENDCAP, int>::type = 0>
0154 inline auto pack_slim_helper(const T& obj) {
0155 static_assert(T::BITWIDTH_ENDCAP_SLIM <= NB, "NB Type is too small for the object");
0156 return obj.pack_endcap_slim();
0157 }
0158
0159 template <unsigned int N, PackingStrategy METHOD = PackingStrategy::DEFAULT, unsigned int OFFS = 0, typename T, int NB>
0160 inline void l1pf_pattern_pack(const T objs[N], ap_uint<NB> data[]) {
0161 #ifdef __SYNTHESIS__
0162 #pragma HLS inline
0163 #pragma HLS inline region recursive
0164 #endif
0165 for (unsigned int i = 0; i < N; ++i) {
0166 #ifdef __SYNTHESIS__
0167 #pragma HLS unroll
0168 #endif
0169 data[i + OFFS] = pack_helper<T, NB, METHOD>(objs[i]);
0170 }
0171 }
0172
0173
0174 template <unsigned int N, unsigned int OFFS, typename T, int NB>
0175 inline void l1pf_pattern_pack(const T objs[N], ap_uint<NB> data[]) {
0176 l1pf_pattern_pack<N, PackingStrategy::DEFAULT, OFFS, T, NB>(objs, data);
0177 }
0178
0179 template <unsigned int N, PackingStrategy METHOD = PackingStrategy::DEFAULT, unsigned int OFFS = 0, typename T, int NB>
0180 inline void l1pf_pattern_unpack(const ap_uint<NB> data[], T objs[N]) {
0181 #ifdef __SYNTHESIS__
0182 #pragma HLS inline
0183 #pragma HLS inline region recursive
0184 #endif
0185 for (unsigned int i = 0; i < N; ++i) {
0186 #ifdef __SYNTHESIS__
0187 #pragma HLS unroll
0188 #endif
0189 objs[i] = unpack_helper<T, NB, METHOD>(data[i + OFFS]);
0190 }
0191 }
0192
0193
0194 template <unsigned int N, unsigned int OFFS, typename T, int NB>
0195 inline void l1pf_pattern_unpack(const ap_uint<NB> data[], T objs[N]) {
0196 l1pf_pattern_unpack<N, PackingStrategy::DEFAULT, OFFS, T, NB>(data, objs);
0197 }
0198
0199 template <unsigned int N, PackingStrategy METHOD = PackingStrategy::DEFAULT, unsigned int OFFS = 0, typename T, int NB>
0200 inline void l1pf_pattern_pack_slim(const T objs[N], ap_uint<NB> data[]) {
0201 #ifdef __SYNTHESIS__
0202 #pragma HLS inline
0203 #pragma HLS inline region recursive
0204 #endif
0205 for (unsigned int i = 0; i < N; ++i) {
0206 #ifdef __SYNTHESIS__
0207 #pragma HLS unroll
0208 #endif
0209 data[i + OFFS] = pack_slim_helper<T, NB, METHOD>(objs[i]);
0210 }
0211 }
0212
0213
0214 template <unsigned int N, unsigned int OFFS, typename T, int NB>
0215 inline void l1pf_pattern_pack_slim(const T objs[N], ap_uint<NB> data[]) {
0216 l1pf_pattern_pack_slim<N, PackingStrategy::DEFAULT, OFFS, T, NB>(objs, data);
0217 }
0218
0219 template <unsigned int N, PackingStrategy METHOD = PackingStrategy::DEFAULT, unsigned int OFFS = 0, typename T, int NB>
0220 inline void l1pf_pattern_unpack_slim(const ap_uint<NB> data[], T objs[N]) {
0221 #ifdef __SYNTHESIS__
0222 #pragma HLS inline
0223 #pragma HLS inline region recursive
0224 #endif
0225 for (unsigned int i = 0; i < N; ++i) {
0226 #ifdef __SYNTHESIS__
0227 #pragma HLS unroll
0228 #endif
0229 objs[i] = unpack_slim_helper<T, NB, METHOD>(data[i + OFFS]);
0230 }
0231 }
0232
0233
0234 template <unsigned int N, unsigned int OFFS, typename T, int NB>
0235 inline void l1pf_pattern_unpack_slim(const ap_uint<NB> data[], T objs[N]) {
0236 l1pf_pattern_unpack_slim<N, PackingStrategy::DEFAULT, OFFS, T, NB>(data, objs);
0237 }
0238
0239 #endif