Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // Enum to define different packing strategies for data encoding
0034 // DEFAULT: Standard packing
0035 // BARREL: Packing strategy for barrel region
0036 // ENDCAP: Packing strategy for endcap region
0037 enum class PackingStrategy { DEFAULT, BARREL, ENDCAP };
0038 
0039 // Default case: Calls T::unpack()
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 // Specialization for BARREL
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 // Specialization for ENDCAP
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 // Default case: Calls T::unpack()
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 // Specialization for BARREL
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 // Specialization for ENDCAP
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 // Default case: Calls T::unpack()
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 // Specialization for BARREL
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 // Specialization for ENDCAP
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 // Default case: Calls T::unpack()
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 // Specialization for BARREL
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 // Specialization for ENDCAP
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 // overlaod for default strategy
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 // overlaod for default strategy
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 // overlaod for default strategy
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 // overlaod for default strategy
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