Coyote/examples_hw/apps/hyperloglog/hls/hllsketch_16x32/hllsketch_16x32.hpp

102 lines
2.4 KiB
C++

#include <hls_stream.h>
#include <stdint.h>
#include <ap_int.h>
#include "HllSketch.hpp"
#include "stream.hpp"
#include "hashes.hpp"
//===========================================================================
// Design Dimensioning
unsigned const N = 16; // Parallel Data Lanes
unsigned const P = 14; // Precision
using Hash = Murmur3_64<0xDEADF00D>;
unsigned const H = 64;
template<unsigned D>
struct net_axis {
ap_uint<D> data;
ap_uint<D/8> keep;
ap_uint<6> id;
ap_uint<1> last;
};
unsigned const DATA_WIDTH = 32;
unsigned const LINE_WIDTH = N*DATA_WIDTH;
using input_t = net_axis<LINE_WIDTH>; // Input Tuple
using item_t = flit_v_t<ap_uint<DATA_WIDTH>>; // Decomposed Input Item
using output_t = net_axis<32>; // Output: Wrapped float
//===========================================================================
// Input Split
static void divide_data(hls::stream<input_t> &src, hls::stream<item_t> (&dst)[N]) {
#pragma HLS PIPELINE II=1
#pragma HLS INLINE off
static item_t buf[N] = {};
static bool flush = false;
if(flush) {
for(unsigned i = 0; i < N; i++) {
#pragma HLS unroll
if(buf[i].last) dst[i].write(buf[i]);
}
flush = false;
}
else {
input_t x;
if(src.read_nb(x)) {
bool const last = x.last;
for(unsigned i = 0; i < N; i++) {
#pragma HLS unroll
bool const keep = (x.keep(4*i+3, 4*i) == 0xF);
dst[i].write(item_t{last&&!keep, buf[i].val});
buf[i] = item_t{keep, x.data((i+1)*DATA_WIDTH-1, i*DATA_WIDTH)};
}
flush = last;
}
}
} // divide_data()
//===========================================================================
void top(
hls::stream<input_t> &s_axis_data,
hls::stream<output_t> &m_axis_card
) {
//#pragma HLS INTERFACE axis port=s_axis_data
//#pragma HLS INTERFACE axis port=m_axis_card
#pragma HLS dataflow
// Split the Data Lanes
static hls::stream<item_t> src_hll[N];
#if defined( __VITIS_HLS__)
#pragma HLS aggregate variable=src_hll compact=bit
#else
#pragma HLS data_pack variable=src_hll
#endif
divide_data(s_axis_data, src_hll);
// HLL Sketch
class YAssign {
output_t& m_y;
public:
YAssign(output_t &y) : m_y(y) {}
void operator=(float v) {
union { float f; uint32_t i; } const conv = { .f = v };
m_y.data = conv.i;
m_y.keep = 0xF;
}
};
static HllSketch<N, H, P> hll_sketch;
hll_sketch.sketch(
src_hll, m_axis_card,
MemberLast(), [](item_t const& x){ return Hash()(x.val); },
MemberLast(), [](output_t &y){ return YAssign(y); }
);
} // top