cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer
Observer
529 Views
Registered: ‎11-21-2017

TE0701-06 with 1Gsps ADC @ DDR --> too slow?

Hi there,

 

I am using a a TE0701-06 Board together with an evalboard of microwave and a ADC HMCAD1520 @ 1GSPS.

So I have implemented the LVDS interface on my Zynq as an custom IP, so on every rising edge of "FCLKP" there are new samples available.

ADC_specs.png

So in my Custom IP I have a hardwarecounter which is counting the rising edges of "FCLKP", what represents the sampled data amount.

Further, to get the sampled data stored, I created a custom IP with HLS, the datalogger IP. My Datalogger Ip is watching the hardwarecounter of my custom IP (LVDS interface), and every time the hardwarecounter changes, my datalogger is writing the sampled data to DDR.

After all I have 8*14Bits = 112Bits which have to be stored, also additional 32bits for the hardwarecounter as a timestamp.

 

@ HLS: I used the "memcpy" command, which is writing the 112+32 Bits at once.

 

#include "datalogger1Gsps.h"
#include <string.h>


unsigned int busBufferSize = 5;

unsigned int dataBus[5];
unsigned int busContainerSize = 5;


unsigned int busIdx = 0;

unsigned int bufferSize1Gsps = 500000;
//unsigned int bufferSize1Gsps = 5000;

unsigned int hwCounterBk = 0;
unsigned int dataCounter = 0;



void data_recorder_HMCAD(int *ddr,
				   unsigned int en,
				   unsigned int freeze,
				   unsigned int hwCounter,
				   unsigned int adcMode,
				   unsigned int smplData0,
				   unsigned int smplData1,
				   unsigned int smplData2,
				   unsigned int smplData3,
				   unsigned int smplData4,
				   unsigned int smplData5,
				   unsigned int smplData6,
				   unsigned int smplData7,
				   unsigned int *ptHwCounterOut)
{
#pragma HLS INTERFACE m_axi depth=500 port=ddr offset=direct

	if(en == 1)
	{
		if(freeze == 0)
		{
			if(hwCounterBk != hwCounter)
			{
				// new Data detected
				hwCounterBk = hwCounter;

				dataBus[busContainerSize * busIdx + 0] = hwCounter;
				dataBus[busContainerSize * busIdx + 1] = smplData1 << 16 | smplData0;
				dataBus[busContainerSize * busIdx + 2] = smplData3 << 16 | smplData2;
				dataBus[busContainerSize * busIdx + 3] = smplData5 << 16 | smplData4;
				dataBus[busContainerSize * busIdx + 4] = smplData7 << 16 | smplData6;

				if(busIdx*busContainerSize >= busBufferSize-busContainerSize)
				{
					memcpy(ddr+dataCounter,dataBus,sizeof(dataBus));
					busIdx = 0;
					dataCounter += busBufferSize;
					dataCounter %= (bufferSize1Gsps);
				}
				else{
					busIdx++;
				}


			}
		}
	}
	else
	{
		dataCounter = 0;
	}


	*ptHwCounterOut = dataCounter;
}

Also here's my design:

design.png

 

So far so good, now the problem I have:

 

To verify if my design is fast enough I built a delphi programm to setup the ADC and to configure the my datalogger and read the stored data @ DDR.

When reading the stored hardwarecounter, i recognize that there are large edges, so the counter isn't continious incremented by 1. So I am  assuming that my DDR is too slow (running at 533MHz).

 

I have a signalgenerator on my ADC to reduce the ADC Clock. When running the ADC @ 10MHz the hardwarecouter is correct, so every stored DDR sample, the hardwarecounter is incremented by 1.

Running the ADC @ 100MHz the hardwarecounter jumps by 5 or more increments...

 

My PL Clock is running @ 250Mhz, which should be fast enough.

ADC @ 1GSPS --> LVDS --> 1GSPS / 8 (data lines) = 125MHz min. PL Clock speed

 

Someone could give me the trick to get faster DDR datarates?

Is the problem @ HLS design (wrong command "memcpy" for writing to DDR?)

0 Kudos
2 Replies
Highlighted
Scholar
Scholar
518 Views
Registered: ‎04-26-2015

Re: TE0701-06 with 1Gsps ADC @ DDR --> too slow?

I expect that the problem is in your HLS code (or rather, in HLS itself). HLS, by default, doesn't tend to do things simultaneously. While it's writing data to RAM (with memcpy), it's going to be completely ignoring the input signal. Copying a single element at a time will make this worse, as AXI Master transfers aren't very efficient unless you can transfer a lot of data at once.

 

If the HLS block is running significantly faster than the ADC data is coming in, you can just stick a big FIFO on the front of it. Provided that the HLS block is fast enough to clear the FIFO before the next lot of data comes in, this should do what you need. Adding internal buffers in the HLS block to increase its throughput (eg. buffer 128 values and then write all of them) will certainly help here. However, there is (as far as I know) no way to make HLS do a read on every single clock cycle - at best it'll read until its internal buffer is full, pause for a few clock cycles (so you need the external FIFO), and continue.

 

An alternative is to set up the system in HDL instead, as this allows you to have much finer control over exactly when different parts are running. With this you absolutely can do a read on every single clock cycle.

0 Kudos
Highlighted
Observer
Observer
511 Views
Registered: ‎11-21-2017

Re: TE0701-06 with 1Gsps ADC @ DDR --> too slow?

Hey u4223374 thanks for your fast response,

 

so I would like to avoid using the DMA IP because it its overkilling features.

Didn't write to DDR without using HLS yet, so sorry for some stupid questions:

 

 

Am I correct when I try to use the datamover for writing to DDR only?

datamover_cmd.png

So I am new to the Datamover, but "SADDR" is my absolute address @ DDR, right?

And "Type" has to be set to "0" if I am writing the absolute address?

BTT would be my array size in bytes, right?

 

 

So at the datamover "s_axis_s2mm_tdata" is my unsigned int data and after setting "s_axis_s2mm_tvalid" I have to wait until the IP says again "s_axis_s2mm_tready" == 1 !?

 

 

datamoverIP.png

 

0 Kudos