AnsweredAssumed Answered

Where to add custom decimation in FMCDAQ2 Reference Design

Question asked by dfa327 on May 4, 2018
Latest reply on May 21, 2018 by dfa327

Hello

  I have a zc706 and an FMCDAQ2.  I'm using the reference design and everything works great out of the box.  Now I want to reduce the ADC sample rate from 1GSps to 4MSps.  I placed a custom decimation IP block between the axi_ad9680_cpack and axi_ad9680_fifo.  All it does is divide by 250, by counting the adc_clk's before it sets the adc_wr bit high.  I've attached the example reference design minus my custom IP block. 

 

System reference design

 

Problem is when I include it, it doesn't seem to get me a nice 4Mhz sample frequency.  It appears I've reduced the sample frequency by a lot more then 250.   I read here (How to reduce sample rate to 1Mbps in of the DAQ2 noOS project for the KCU105? ) that I'd need a custom decimation filter, but I'm not sure I'm placing it in the correct place.  I'm assuming the adc_clk is 250Mhz.  Is that a safe assumption?  Should I place my decimate IP someplace else?

 

Here's where I placed my custom ip I wrote with HLS:

Custom Divider IP Core

 

Here is the code I wrote in HLS to create my custom divider ip core.

 

Here's my divider.h file:

#ifndef _DIVIDER_H_
#define _DIVIDER_H_

 

#include <ap_cint.h>
#include <stdio.h>

 


typedef volatile bool dinb_t;
typedef volatile uint128 din_t;

 

typedef volatile bool doutb_t;
typedef volatile bool * doutb_pt;
typedef volatile uint128 dout_t;
typedef volatile uint128 * dout_pt;

 


void divider(dinb_t in_adc_valid,
        din_t in_adc_data,
        doutb_pt out_adc_valid,
        dout_pt out_adc_data);

 

#endif

 

Here's my divider.c file:

#include "divider.h"

 

uint6 dividerCount = 0;

 

#define DIVIDER_K 62 //Approximately 4Mhz sample, assuming 4 samples at 250Mhz

 

void divider(dinb_t in_adc_valid,
        din_t in_adc_data,
        doutb_pt out_adc_valid,
        dout_pt out_adc_data)
{
#pragma HLS INTERFACE ap_none port=out_adc_data
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=out_adc_valid
#pragma HLS INTERFACE ap_none port=in_adc_data
#pragma HLS INTERFACE ap_none port=in_adc_valid
#pragma HLS PIPELINE
    dout_t tmp_in_adc_data = in_adc_data;

 

    *out_adc_valid = false;

 


    if ( in_adc_valid == true)
    {
        if (++dividerCount == DIVIDER_K)
        {
            dividerCount = 0;

 

            *out_adc_valid = true;
        }
    }
    *out_adc_data = in_adc_data;
}

Outcomes