This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AFE7950EVM: Ramp Pattern issue and ADC Counts issue

Part Number: AFE7950EVM
Other Parts Discussed in Thread: AFE7950

Tool/software:  Latte, MATLAB

Hi, I am using the Xilinx JESD204B IP to configure 4 Rx channels, with the FB and Tx channels not in use.

First, I generated a ramp pattern for all channels. I observed that the ADC counts for Channel D and Channel C were the same (the correct ramp pattern was generated, and both Channels D and C shared the same ramp pattern). However, this was different from the ramp pattern for Channel A and Channel B (the correct ramp pattern was generated, and both Channel A and Channel B shared the same ramp pattern). I have attached the Latte script for reference.

Latte script:

setupParams.skipFpga 				= 1
sysParams							=	AFE.systemParams
#setupParams.fpgaRefClk 				= 122.88
setupParams.fpgaRefClk 				= 245.76	
AFE.systemStatus.loadTrims			= 1

sysParams.FRef                    	= 491.52
sysParams.FadcRx                  	= 2949.12
sysParams.FadcFb				  	= 2949.12
sysParams.Fdac                    	= 2949.12*3
#sysParams.FRef                    	= 500
#sysParams.FadcRx                  	= 3000
#sysParams.FadcFb				  	= 3000
#sysParams.Fdac                    	= 9000

#sysParams.rxEnable                  =   [True,False,False,False]
sysParams.rxEnable		            =	[True,True,True,True]
sysParams.txEnable                  =   [True,True,False,False]
sysParams.enableDacInterleavedMode	= False 					#DAC interleave mode to save power consumption. Fs/2 - Fin spur occurs

sysParams.modeTdd 					= 0		
										# 0- Single TDD Pin for all Channels
										# 1- Separate Control for 2T/2R/1F
										# 2- Separate Control for 1T/1R/1F			

sysParams.topLevelSystemMode		= 'StaticTDDMode'
sysParams.RRFMode 					= 0   #4T4R2F FDD mode
#sysParams.jesdSystemMode			= [3,3]
sysParams.jesdSystemMode			= [0,0]
										#SystemMode 0:	2R1F-FDD						; rx1-rx2-fb-fb
										#SystemMode 1:	1R1F-FDD						; rx1-rx1-fb-fb
										#SystemMode 2:	2R-FDD							; rx1-rx1-rx2-rx2
										#SystemMode 3:	1R								; rx1-rx1-rx1-rx1
										#SystemMode 4:	1F								; fb-fb-fb-fb
										#SystemMode 5:	1R1F-TDD						; rx1/fb-rx1/fb-rx1/fb-rx1/fb
										#SystemMode 8:	1R1F-TDD 1R-FDD	(FB-2Lanes)(RX1 RX2 interchanged)		; rx2/fb-rx2/fb-rx1-rx1


sysParams.jesdLoopbackEn			= 0 #Make it 1 to Enable the JESDTX to JESDRX internal loopback
#sysParams.LMFSHdRx                	=['12410', '12410', '12410', '12410']
sysParams.LMFSHdRx                	=['12410', '12410', '12410', '12410']

										# The 2nd and 4th are valid only for jesdSystemMode values in (2,6,7,8). For other modes, select 4 converter modes for 1st and 3rd.
sysParams.LMFSHdFb                	= ["22210","22210"]
#sysParams.LMFSHdTx                	= ["24410","24410","24410","24410"]
sysParams.LMFSHdTx                	= ["12410","12410","12410","12410"]
sysParams.jesdTxProtocol            = [0,0]
sysParams.jesdRxProtocol            = [0,0]
sysParams.serdesFirmware			= True 		# If you want to lead any firmware, please speify the path here. Otherwise it will not write any firmware
# sysParams.jesdTxLaneMux				= [0,1,2,3,4,5,6,7]
# sysParams.jesdTxLaneMux				= [4,5,2,3,0,1,6,7]	
sysParams.jesdTxLaneMux				= [6,7,2,3,4,5,0,1]	 #Jesd ip 4 channel
#sysParams.jesdTxLaneMux				= [2,3,0,1,6,7,4,5]
												# Enter which lanes you want in each location. 
												# Note that across 2T Mux is not possible in 0.5.
												# For example, if you want to exchange the first two lines of each 2T, this should be [[1,0,2,3],[5,4,6,7]]
sysParams.jesdRxLaneMux				= [0,1,2,3,4,5,6,7]	
												# Enter which lanes you want in each location.
												# Note that across 2R Mux is not possible in 0.5.
												# For example, if you want to exchange the first two lines of each 2R, this should be [[1,0,2,3],[5,4,6,7]]
												
sysParams.dacDataMuxEn      =  1 #to enable datamux
sysParams.txDataMux					= [0,1,4,5,2,3,6,7]
#sysParams.txDataMux					= [0,1,2,3,4,5,6,7]


sysParams.adcDataMuxEn = 1
sysParams.rxDataMux =  [0,1,2,3,6,7,4,5]
#sysParams.rxDataMux =  [6,7,4,5,0,1,2,3]

sysParams.jesdRxRbd					= [4, 4]
sysParams.jesdTxRbd					= [1, 1]

sysParams.rxJesdTxScr				= [False,False,False,False]
sysParams.fbJesdTxScr				= [False,False]
sysParams.jesdRxScr					= [False,False,False,False]

sysParams.rxJesdTxK					= [32,32,32,32]
sysParams.fbJesdTxK					= [32,32]
sysParams.jesdRxK					= [32,32,32,32]

#sysParams.ncoFreqMode 				= "1KHz"
sysParams.ncoFreqMode 				= "FCW"	
sysParams.txNco0					= 	[[5000,5000],		#Band0, Band1 for TxA for NCO0
										[5000,5000],        #Band0, Band1 for TxB for NCO0
										[5000,5000],        #Band0, Band1 for TxC for NCO0
										[5000,5000]]        #Band0, Band1 for TxD for NCO0


sysParams.rxNco0					= 	[[5000,5000],		#Band0, Band1 for RxA for NCO0
										[5000,5000],        #Band0, Band1 for RxB for NCO0
										[5000,5000],        #Band0, Band1 for RxC for NCO0#
										[5000,5000]]        #Band0, Band1 for RxD for NCO0

#sysParams.rxNco0					= 	[[200,200],		 #Band0, Band1 for RxA for NCO0
#									[200,200],        #Band0, Band1 for RxB for NCO0
#									[200,200],        #Band0, Band1 for RxC for NCO0
#									[200,200]]        #Band0, Band1 for RxD for NCO0


sysParams.fbNco0					= 	[2600,2600]			#FBA, FBC for NCO0


sysParams.numBandsRx				= [0]*4					# 0 for single, 1 for dual
sysParams.numBandsFb				= [0,0]				
sysParams.numBandsTx				= [0,0,0,0]

#sysParams.ddcFactorRx             	= [24,24,24,24]			# DDC decimation factor for RX A, B, C and D #for 122.88 and 21916.12*3
sysParams.ddcFactorRx             	= [12,12,12,12]			# DDC decimation factor for RX A, B, C and D
sysParams.ddcFactorFb             	= [12,12]
sysParams.ducFactorTx             	= [36,36,36,36]
#sysParams.ducFactorTx             	= [72,72,72,72]    #for 122.88 and 21916.12*3
#sysParams.ddcFactorFb             	= [6,6]   #for 122.88 and 21916.12*3
#sysParams.ddcFactorRx             	= [12,12,12,12]			# DDC decimation factor for RX A, B, C and D #for 245.76 and 21916.12*3
#sysParams.ddcFactorFb             	= [6,6]   #for 245.76 and 21916.12*3
#sysParams.ducFactorTx             	= [36,36,36,36]    #for 245.76 and 21916.12*3

## The following parameters sets up the LMK04828 clocking schemes
lmkParams.pllEn						=	True#False
lmkParams.inputClk					=	1474.56#737.28
#lmkParams.sysrefFreq				=	3.84
lmkParams.sysrefFreq				=	7.68
lmkParams.lmkFrefClk				=	True

## The following parameters sets up the register and macro dumps
logDumpInst.setFileName(ASTERIX_DIR+DEVICES_DIR+r"\Afe79xxPg1.txt")
logDumpInst.logFormat				= 0x21
logDumpInst.rewriteFile				= 1
logDumpInst.rewriteFileFormat4		= 1
device.optimizeWrites				= 0
device.rawWriteLogEn				= 1

## The following parameters sets up the SYNCIN and SYNCOUT to interface with the TSW14J57
#sysParams.jesdABLvdsSync			= 1
#sysParams.jesdCDLvdsSync			= 1
sysParams.jesdABLvdsSync			= 0
sysParams.jesdCDLvdsSync			= 0
sysParams.rxJesdTxSyncMux			= [0,0,0,0]
sysParams.fbJesdTxSyncMux			= [0,0]
sysParams.jesdRxSyncMux				= [0,0,0,0]		#[0,0,1,1]
sysParams.syncLoopBack				= True

## The following parameters sets up the AGC
#sysParams.agcParams[0].agcMode = 1 ##internal AGC
#sysParams.agcParams[0].gpioRstEnable = 0 ##disable GPIO based reset to AGC detector 
#sysParams.agcParams[0].atken = [0, 0, 0] ##enable big and small step attack
#sysParams.agcParams[0].decayen = [1,1,1] ##enable big and small step decay
#sysParams.agcParams[0].atksize = [4,2,1] ## bigs step = 2dB, small step = 1dB
#sysParams.agcParams[0].decaysize = [10,5,1] ##big step = 2dB, small step = 1dB
#sysParams.agcParams[0].atkthreshold = [-1, -2, -14] ##attack threshold
#sysParams.agcParams[0].decaythreshold = [-3, -4, -16] ##decay threshold
#sysParams.agcParams[0].atkwinlength = [170, 170] ## detector time constant expressed inn absolute time in ns. 
#sysParams.agcParams[0].decaywinlength = 20346 ##detector time constant expressed in absolute time in ns. All detectors use the same value for decay time constant
#sysParams.agcParams[0].atkNumHitsAbs = [8,8] ##absolute number of times signal crosses threshold. These crossing are with respect to the FADC/8 clock
#sysParams.agcParams[0].decayNumHitsAbs = [3000,3000] ##absolute number of times signal crosses threshold. These crossing are with respect to the FADC/8 clock
#sysParams.agcParams[0].minDsaAttn = 0 ##minimum DSA attenuation used by AGC
#sysParams.agcParams[0].maxDsaAttn = 50 ##maximum DSA attenuation used by AGC
#sysParams.agcParams[0].totalGainRange = 25 ##total gain range used by ALC for gain compensation



#sysParams.agcParams[0].minAttnAlc = 0 ##minimum attenuation used by ALC for compensation when useMinAttnAgc = 0
#sysParams.agcParams[0].useMinAttnAgc = 1 ##enable ALC to use minimum attenuation from AGC for which compensation is required.
#sysParams.agcParams[0].alcEn = 1
#sysParams.agcParams[0].alcMode = 0 ##floating point DGC
#sysParams.agcParams[0].fltPtMode = 0 ##if exponent > 0, dont send MSB
#sysParams.agcParams[0].fltPtFmt = 1 ##3 bit exponent

## lna control parameters added later on
#sysParams.agcParams[0].lnaEn = 1
#sysParams.agcParams[0].lnaGainMargin = 2


## The following parameters sets up the GPIOs
sysParams.gpioMapping={
		'H8': 'ADC_SYNC0',
		#'H7': 'ADC_SYNC1',
		'H7': 'DAC_SYNC0',
		'N8': 'ADC_SYNC2',
		'N7': 'ADC_SYNC3',
		#'H9': 'DAC_SYNC0',
		'H9': 'ADC_SYNC1',
		'G9': 'DAC_SYNC1',
		'N9': 'DAC_SYNC2',
		'P9': 'DAC_SYNC3',
		'P14': 'GLOBAL_PDN',
		'K14': 'FBABTDD',
		'R6': 'FBCDTDD',
		'H15': ['TXATDD','TXBTDD'],
		'V5': ['TXCTDD','TXDTDD'],
		'E7': ['RXATDD','RXBTDD'],
		'R15': ['RXCTDD','RXDTDD']}
		
#AFE.systemParams.papParams[0]['enable'] = True
#AFE.systemParams.papParams[1]['enable'] = True
#AFE.systemParams.papParams[2]['enable'] = True
#AFE.systemParams.papParams[3]['enable'] = True
		

## Initiates LMK04828 and AFE79xx Bring-up
setupParams.skipLmk	=	False

AFE.initializeConfig()
lmkParams.sysrefFreq = AFE.systemStatus.sysrefFreq
lmkParams.lmkPulseSysrefMode = False
AFE.LMK.lmkConfig()
## Initiates AFE79xx Bring-up
setupParams.skipLmk	=	True
AFE.deviceBringup()

AFE.TOP.overrideTdd(15,0,15)
#AFE.JESD.ADCJESD[0].adcRampTestPattern(0,1,0)
#AFE.JESD.ADCJESD[0].adcRampTestPattern(1,1,0)
#AFE.JESD.ADCJESD[1].adcRampTestPattern(0,1,0)
#AFE.JESD.ADCJESD[1].adcRampTestPattern(1,1,0)



# AFE.JESD.DACJESD[0].dacJesdConstantTestPatternValue(1,0,0,32767,0)
# AFE.JESD.DACJESD[0].dacJesdConstantTestPatternValue(1,1,0,32767,0)
# 
# AFE.JESD.DACJESD[1].dacJesdConstantTestPatternValue(1,0,0,32767,0)
# AFE.JESD.DACJESD[1].dacJesdConstantTestPatternValue(1,1,0,32767,0)

Next, I applied a signal of 5.01 GHz at -5 dBm (with the NCOs of all channels set to 5 GHz) to all channels through a power divider. I observed a difference in ADC counts between the channels. I have attached the MATLAB plots showing the ADC counts of the sine wave's peaks, for all channels.

MATLAB Plots:

         

  1. Why are the ramp patterns of Channel A and Channel B different from those of Channel C and Channel D?
  2. Why is there a difference in the ADC counts between the channels when the same signal is applied?
  3. On ChipScope, the waveform generated by the ADC is 16-bit. Why is this the case, given that the AFE7950 has 14-bit ADCs? I have checked for sign-extension, but that does not seem to be the issue, as the maximum count reached by the ADC is ±2^15."

Regards,

Umer Siddiq

  • Hi Umer,

    What looks to be happening with the ramp pattern is that the AFE is designed as two subchips, each 2T2R1F, and the ramp pattern for the two subchips is separate. I will check with our software team to see if there is any way to enable the ramp pattern for both subchips at the same time or to align them . 

    The difference in the ADC counts between channels is most likely caused by differences in routing on the EVM and AFE substrate. A and C should be mirrors of each other, do they have similar amplitudes in your test? 

    Regards,

    David Chaparro 

  • Hi David,

    Apologies for the delayed response. As you mentioned, Channels A and C indeed have similar amplitudes. After some investigation, my team traced the issue to the circuit following the SMA connectors. It turns out that the components in the circuits for Channels A and C differ from those for Channels B and D, which likely explains the amplitude discrepancies.

    Regarding the ramp pattern issue, our application requires the phase difference between channels to remain zero. My question is: if there's a misalignment observed in the ramp pattern test, would this misalignment also appear in the analog signal? And if it does, what would be the best way to correct it?

    Best Regards,
    Umer Siddiq

  • Hi Umer,


    The issue you are seeing is only for the test pattern as they are being set independently for each subchip. For the phase differences caused by matching circuits and routing you can update the phase of the Rx/Tx NCOs. The AFE7950 has a 16bit register to control the phase of each channels NCO. This means that you can adjust the phase of the NCO in steps of 360/2^16 = 0.00549 degrees.

    Regards,

    David Chaparro