Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:25

0001 #ifndef CC_INVERSION_H__
0002 #define CC_INVERSION_H__
0003 
0004 namespace l1ct {
0005 
0006   constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); }
0007 
0008   template <class data_T, int N>
0009   inline float real_val_from_idx(unsigned i) {
0010     // Treat the index as the top N bits
0011     static constexpr int NB = ceillog2(N);  // number of address bits for table
0012     data_T x(0);
0013     // The MSB of 1 is implicit in the table
0014     x[x.width - 1] = 1;
0015     // So we can use the next NB bits for real data
0016     x(x.width - 2, x.width - NB - 1) = i;
0017     return (float)x;
0018   }
0019 
0020   template <class data_T, int N>
0021   inline unsigned idx_from_real_val(data_T x) {
0022     // Slice the top N bits to get an index into the table
0023     static constexpr int NB = ceillog2(N);  // number of address bits for table
0024     // Slice the top-1 NB bits of the value
0025     // the MSB of '1' is implicit, so only slice below that
0026     ap_uint<NB> y = x(x.width - 2, x.width - NB - 1);
0027     return (unsigned)y(NB - 1, 0);
0028   }
0029 
0030   template <class data_T, class table_T, int N>
0031   void init_invert_table(table_T table_out[N]) {
0032     // The template data_T is the data type used to address the table
0033     for (unsigned i = 0; i < N; i++) {
0034       float x = real_val_from_idx<data_T, N>(i);
0035       table_T inv_x = 1 / x;
0036       table_out[i] = inv_x;
0037     }
0038   }
0039 
0040   template <class in_t, class table_t, int N>
0041   table_t invert_with_shift(in_t in) {
0042     table_t inv_table[N];
0043     init_invert_table<in_t, table_t, N>(inv_table);
0044 
0045     // find the first '1' in the denominator
0046     int msb = 0;
0047     for (int b = 0; b < in.width; b++) {
0048       // #pragma HLS unroll
0049       if (in[b])
0050         msb = b;
0051     }
0052     // shift up the denominator such that the left-most bit (msb) is '1'
0053     in_t in_shifted = in << (in.width - msb - 1);
0054     // lookup the inverse of the shifted input
0055     int idx = idx_from_real_val<in_t, N>(in_shifted);
0056     table_t inv_in = inv_table[idx];
0057     // shift the output back
0058     table_t out = inv_in << (in.width - msb - 1);
0059     return out;
0060   }
0061 
0062 }  // namespace l1ct
0063 #endif