typedef int32_t MyData;
#define BLOCK 128
const unsigned int BSIZE = BLOCK;

#pragma omp target device(fpga)
#pragma omp task in([BSIZE]in) out([BSIZE]histog)
void histogram(const MyData  *const restrict in,
	             MyData  *const restrict histog,
	       const u_int8_t                copy_out,
	       const u_int8_t                reset)

{
#pragma HLS inline off

  static u_int32_t local_histog[BLOCK];

  if (reset)
    {
    loop_reset:
      for (u_int16_t i=0 ; i<BLOCK ; i++)
	{
	  local_histog[i] = 0;
	}
    }

/**************************************************************/

  /* load the first value */
  MyData old_value = in[0];

  /* accumulator */
  MyData acc = local_histog[old_value];

 loop_histogram:
  for (u_int16_t i=0 ; i<BLOCK ; i++)
    {
      /* load value */
      MyData value = in[i];
      
      if (old_value == value) /* get the same value */
	{
	  acc++;
	}
      else /* different value */
	{
	  local_histog[old_value] = acc;
	  acc = (local_histog[value] + 1);
	}

      /* update the old value */
      old_value = value;
    } /* loop */

  local_histog[old_value] = acc;

/**************************************************************/

  /* copy local_histog to histog */
  if (copy_out)
    {
    loop_copy:
      for (u_int16_t i=0 ; i<BLOCK ; i++)
	{
	  histog[i] = local_histog[i];
	}
    }

  return;
}


/********************** VIVADO HLS REPORT ********************/
/* Target Board: ZedBoard                                    */
/*************************************************************/
/* DSP48E      0 used |    220 available -  0.0% utilization */
/* BRAM_18K    9 used |    280 available - 3.21% utilization */
/* LUT      8372 used |  53200 available -15.91% utilization */
/* FF       5237 used | 106400 available - 5.04% utilization */
/*************************************************************/
