cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
yawenluo16
Observer
Observer
711 Views
Registered: ‎05-28-2019

PS to DAC Using JESD204

Jump to solution

I'm working on communication between PS and DAC. Need a tutorial on JESD204B Rx design example.

My status:
FPGA board: Zynq UltraScale+ MPSoC ZCU102;
DAC: TI DAC38J84EVM kit.
I've gone through the v7.2 LogiCORE IP Product Guide, and JESD PYH Guide, but still confused about how to achieve the interconnections of JESD204, PS and other AXI interfaces IP core. And the correlated SDK software applications.

My Questions:
1. Do I need an extra license for JESD204 IP core? Right now my IP catalog shows the license column as: "JESD204->Purchase; JESD204 PHY->Included".

2. JESD204 Lounge seems no longer provide any example demos.
While I'm searching the Forum for help, someone mentioned that the JESD Lounge contains the hardware demo and everything need to start from scratch, but I can only find some JESD204 and JESD204 PHY Guides.

3. Where can I find some design examples about JESD projects, which I can learn both hardware platform building using Vivado and software application grammar using SDK?

 

Capture.PNG
0 Kudos
1 Solution

Accepted Solutions
schumerth
Adventurer
Adventurer
630 Views
Registered: ‎06-05-2015

Seems like I found another one of your post.

 

Go to the ip catalog search for JESD.  Right click and select product guide, chapter five will show you how to create an example design.

If you want an axample design for any IP, search for said IP and cutomize as default.  Generate the files.  Right click the output and select the open example design.

 

AS for SDK, I am not much help but here is what I have,  I still have not achieved sync with my part yet.  In the IP setup you select  either RX or TX.  Using the Block design might be easier than creating in VHDL or Verilog.

 

/*
 * JESD_ops.c
 *
 *  Created on: Aug 20, 2019
 *      Author: david.schumerth
 */

#include "jesd_ops.h"
#include <stdio.h>


uint32_t jesd_read_reg(uint32_t offset, uint32_t baseAddr)
{
  uint32_t rtn = 0;
  /*uint32_t baseAddr;

  if(adc == JESD_BASE_ADCB)
    baseAddr = JESD_BASE_ADCB;
  else
    baseAddr = JESD_BASE_ADC;*/

  rtn = Xil_In32( baseAddr + offset );
  return rtn;
}

void jesd_init(void)
{
	jesd_init_adc();
}

void jesd_status(void)
{
	jesd_status_adc();
}

void jesd_init_adc(void)
{
	u32 reg;
	uint32_t baseAddr = JESD_BASE_ADC;

	// Check version
	reg = Xil_In32( baseAddr );
	printf("ADC JESD Core Version 0x%.X\n", (unsigned int)reg );

	// Reset Core
	//printf("ADC Software JESD204B Reset ... " );
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	Xil_Out32( baseAddr + ADC_JESD_rst, 0x00010001 ); //this bit may need to be changed
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	while( reg & 0x1 )
	{
	  reg = Xil_In32( baseAddr + ADC_JESD_rst );
	}
	printf("complete\n" );

	// ILA Support
	reg = Xil_In32( baseAddr + ADC_JESD_ila );
	Xil_Out32( baseAddr + ADC_JESD_ila, 0x01 );
	reg = Xil_In32( baseAddr + ADC_JESD_ila );
	//printf("DAC ILA Support Reg 0x%0.8X\n", reg );

	// Sysref
	Xil_Out32( baseAddr + ADC_JESD_sysrefH, 0x00010001 );
	reg = Xil_In32( baseAddr + ADC_JESD_sysrefH );
	//printf("DAC SYSREF Reg 0x%0.8X\n", reg );

	// Multiframes in ILA = 4  //this register is used for TX only
	//Xil_Out32( baseAddr + 0x014, 0x3 );
	//reg = Xil_In32( baseAddr + 0x014 );
	//printf("DAC Multiframe in ILA Reg 0x%0.8X\n", reg );

	// Test mode normal
	Xil_Out32( baseAddr + ADC_JESD_test, 0x0 ); // Test Mode off
	reg = Xil_In32( baseAddr + ADC_JESD_test );
	//printf("DAC Test mode Reg 0x%0.8X\n", reg );

	// Octets per frame, F
	Xil_Out32( baseAddr + ADC_JESD_octets, ADC_JESD_F-1 );
	reg = Xil_In32( baseAddr + ADC_JESD_octets );
	//printf("DAC F Reg 0x%0.8X\n", reg );

	// Frames per multiframe, K
	Xil_Out32( baseAddr + ADC_JESD_frames, ADC_JESD_K-1 );
	reg = Xil_In32( baseAddr + ADC_JESD_frames );
	//printf("DAC K Reg 0x%0.8X\n", reg );

	// Lanes in Use
	Xil_Out32( baseAddr + ADC_JESD_lanes, ADC_JESD_ACTIVE_LANES );
	reg = Xil_In32( baseAddr + ADC_JESD_lanes );
	//printf("DAC L Reg 0x%0.8X\n", reg );

	// Subclass
	Xil_Out32( baseAddr + ADC_JESD_subclass, 0x001 );
	reg = Xil_In32( baseAddr + ADC_JESD_subclass );
	//printf("DAC Subclass Reg 0x%0.8X\n", reg );

	// Scrambling
	Xil_Out32( baseAddr + ADC_JESD_Scrambling, 0x001 );
	reg = Xil_In32( baseAddr + ADC_JESD_Scrambling );
	//printf("DAC Scambling Reg 0x%0.8X\n", reg );

	// Board ID/Device ID
//	Xil_Out32( JESD_BASE + 0x80C, 0x00000412 );
//	reg = Xil_In32( JESD_BASE + 0x024 );
//	printf("BID DID Reg 0x%0.8X\n", reg );

	// setup lane parameters
	/*unsigned int i = 0;
	for(i = 0; i < 8; i++)
	{
	  jesd_setup_lane(i);
	}*/

	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	Xil_Out32( baseAddr + ADC_JESD_rst, 0x1 );
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	while( reg & 0x1 )
	{
		reg = Xil_In32( baseAddr + ADC_JESD_rst );
	}
	printf("complete\n" );
	printf("--------------END------------\n");
}

void jesd_setup_lane(uint8_t lane)
{
  uint32_t baseAddr = JESD_BASE_ADC;
  uint32_t offset = lane * 0x40;

  // ila config data 3
  Xil_Out32( baseAddr + 0x80C + offset, 0x00000412 );// bank id and device id

  // ila config data 4
  Xil_Out32( baseAddr + 0x810 + offset, 0x00101002 );
  // control bits per sample = 0
  //total bits per sample = 16
  //converter resolution = 16
  //converters per device = 2

  // ila config data5
  Xil_Out32( baseAddr + 0x814 + offset, 0x00010200 );
  // control words per frame = 0
  // High density format = 1 (per ad9162 datasheet)
  // Samples per converter per frame = 2
}

uint8_t jesd_getStat_sync_adc(void)
{
	uint32_t regVal = Xil_In32(JESD_BASE_ADC + ADC_JESD_sync);
	return (uint8_t)(regVal & 0x00000001);
}

uint8_t jesd_getStat_sysref_adc(void)
{
	uint32_t regVal = Xil_In32(JESD_BASE_ADC + ADC_JESD_sync);
	return (uint8_t)((regVal & 0x00010000)>>16);
}

void jesd_status_adc(void)
{
	uint32_t baseAddr = JESD_BASE_ADC;
	u32 reg = Xil_In32( baseAddr + ADC_JESD_test );
	int sysref_cap = -1;
	int sync = -1;

	reg = Xil_In32( baseAddr + ADC_JESD_sync );
	if( reg & 0x00010000 )
	{
		if( sysref_cap != 1 )
		{
			//printf("DAC: SYSREF Captured\n\r");
			sysref_cap = 1;
		}
	}
	else
	{
		if( sysref_cap != 0 )
		{
			//printf("DAC: SYSREF NOT Captured\n\r");
			sysref_cap = 0;
		}
	}
	if( reg & 0x00000001 )
	{
		if( sync != 1 )
		{
			//printf("DAC: Link SYNC Achieved\n\r");
			sync = 1;
		}
	}
	else
	{
		if( sync != 0 )
		{
			//printf("DAC: Link SYNC NOT Achieved\n\r");
			sync = 0;
		}
	}
}

.

View solution in original post

2 Replies
schumerth
Adventurer
Adventurer
631 Views
Registered: ‎06-05-2015

Seems like I found another one of your post.

 

Go to the ip catalog search for JESD.  Right click and select product guide, chapter five will show you how to create an example design.

If you want an axample design for any IP, search for said IP and cutomize as default.  Generate the files.  Right click the output and select the open example design.

 

AS for SDK, I am not much help but here is what I have,  I still have not achieved sync with my part yet.  In the IP setup you select  either RX or TX.  Using the Block design might be easier than creating in VHDL or Verilog.

 

/*
 * JESD_ops.c
 *
 *  Created on: Aug 20, 2019
 *      Author: david.schumerth
 */

#include "jesd_ops.h"
#include <stdio.h>


uint32_t jesd_read_reg(uint32_t offset, uint32_t baseAddr)
{
  uint32_t rtn = 0;
  /*uint32_t baseAddr;

  if(adc == JESD_BASE_ADCB)
    baseAddr = JESD_BASE_ADCB;
  else
    baseAddr = JESD_BASE_ADC;*/

  rtn = Xil_In32( baseAddr + offset );
  return rtn;
}

void jesd_init(void)
{
	jesd_init_adc();
}

void jesd_status(void)
{
	jesd_status_adc();
}

void jesd_init_adc(void)
{
	u32 reg;
	uint32_t baseAddr = JESD_BASE_ADC;

	// Check version
	reg = Xil_In32( baseAddr );
	printf("ADC JESD Core Version 0x%.X\n", (unsigned int)reg );

	// Reset Core
	//printf("ADC Software JESD204B Reset ... " );
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	Xil_Out32( baseAddr + ADC_JESD_rst, 0x00010001 ); //this bit may need to be changed
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	while( reg & 0x1 )
	{
	  reg = Xil_In32( baseAddr + ADC_JESD_rst );
	}
	printf("complete\n" );

	// ILA Support
	reg = Xil_In32( baseAddr + ADC_JESD_ila );
	Xil_Out32( baseAddr + ADC_JESD_ila, 0x01 );
	reg = Xil_In32( baseAddr + ADC_JESD_ila );
	//printf("DAC ILA Support Reg 0x%0.8X\n", reg );

	// Sysref
	Xil_Out32( baseAddr + ADC_JESD_sysrefH, 0x00010001 );
	reg = Xil_In32( baseAddr + ADC_JESD_sysrefH );
	//printf("DAC SYSREF Reg 0x%0.8X\n", reg );

	// Multiframes in ILA = 4  //this register is used for TX only
	//Xil_Out32( baseAddr + 0x014, 0x3 );
	//reg = Xil_In32( baseAddr + 0x014 );
	//printf("DAC Multiframe in ILA Reg 0x%0.8X\n", reg );

	// Test mode normal
	Xil_Out32( baseAddr + ADC_JESD_test, 0x0 ); // Test Mode off
	reg = Xil_In32( baseAddr + ADC_JESD_test );
	//printf("DAC Test mode Reg 0x%0.8X\n", reg );

	// Octets per frame, F
	Xil_Out32( baseAddr + ADC_JESD_octets, ADC_JESD_F-1 );
	reg = Xil_In32( baseAddr + ADC_JESD_octets );
	//printf("DAC F Reg 0x%0.8X\n", reg );

	// Frames per multiframe, K
	Xil_Out32( baseAddr + ADC_JESD_frames, ADC_JESD_K-1 );
	reg = Xil_In32( baseAddr + ADC_JESD_frames );
	//printf("DAC K Reg 0x%0.8X\n", reg );

	// Lanes in Use
	Xil_Out32( baseAddr + ADC_JESD_lanes, ADC_JESD_ACTIVE_LANES );
	reg = Xil_In32( baseAddr + ADC_JESD_lanes );
	//printf("DAC L Reg 0x%0.8X\n", reg );

	// Subclass
	Xil_Out32( baseAddr + ADC_JESD_subclass, 0x001 );
	reg = Xil_In32( baseAddr + ADC_JESD_subclass );
	//printf("DAC Subclass Reg 0x%0.8X\n", reg );

	// Scrambling
	Xil_Out32( baseAddr + ADC_JESD_Scrambling, 0x001 );
	reg = Xil_In32( baseAddr + ADC_JESD_Scrambling );
	//printf("DAC Scambling Reg 0x%0.8X\n", reg );

	// Board ID/Device ID
//	Xil_Out32( JESD_BASE + 0x80C, 0x00000412 );
//	reg = Xil_In32( JESD_BASE + 0x024 );
//	printf("BID DID Reg 0x%0.8X\n", reg );

	// setup lane parameters
	/*unsigned int i = 0;
	for(i = 0; i < 8; i++)
	{
	  jesd_setup_lane(i);
	}*/

	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	Xil_Out32( baseAddr + ADC_JESD_rst, 0x1 );
	reg = Xil_In32( baseAddr + ADC_JESD_rst );
	while( reg & 0x1 )
	{
		reg = Xil_In32( baseAddr + ADC_JESD_rst );
	}
	printf("complete\n" );
	printf("--------------END------------\n");
}

void jesd_setup_lane(uint8_t lane)
{
  uint32_t baseAddr = JESD_BASE_ADC;
  uint32_t offset = lane * 0x40;

  // ila config data 3
  Xil_Out32( baseAddr + 0x80C + offset, 0x00000412 );// bank id and device id

  // ila config data 4
  Xil_Out32( baseAddr + 0x810 + offset, 0x00101002 );
  // control bits per sample = 0
  //total bits per sample = 16
  //converter resolution = 16
  //converters per device = 2

  // ila config data5
  Xil_Out32( baseAddr + 0x814 + offset, 0x00010200 );
  // control words per frame = 0
  // High density format = 1 (per ad9162 datasheet)
  // Samples per converter per frame = 2
}

uint8_t jesd_getStat_sync_adc(void)
{
	uint32_t regVal = Xil_In32(JESD_BASE_ADC + ADC_JESD_sync);
	return (uint8_t)(regVal & 0x00000001);
}

uint8_t jesd_getStat_sysref_adc(void)
{
	uint32_t regVal = Xil_In32(JESD_BASE_ADC + ADC_JESD_sync);
	return (uint8_t)((regVal & 0x00010000)>>16);
}

void jesd_status_adc(void)
{
	uint32_t baseAddr = JESD_BASE_ADC;
	u32 reg = Xil_In32( baseAddr + ADC_JESD_test );
	int sysref_cap = -1;
	int sync = -1;

	reg = Xil_In32( baseAddr + ADC_JESD_sync );
	if( reg & 0x00010000 )
	{
		if( sysref_cap != 1 )
		{
			//printf("DAC: SYSREF Captured\n\r");
			sysref_cap = 1;
		}
	}
	else
	{
		if( sysref_cap != 0 )
		{
			//printf("DAC: SYSREF NOT Captured\n\r");
			sysref_cap = 0;
		}
	}
	if( reg & 0x00000001 )
	{
		if( sync != 1 )
		{
			//printf("DAC: Link SYNC Achieved\n\r");
			sync = 1;
		}
	}
	else
	{
		if( sync != 0 )
		{
			//printf("DAC: Link SYNC NOT Achieved\n\r");
			sync = 0;
		}
	}
}

.

View solution in original post

yawenluo16
Observer
Observer
626 Views
Registered: ‎05-28-2019
Really appreciate your efforts on my case! Thanks for the tips about looking into the Example Design of different IPs. And especially, your code does help newbies like me a lot! Thanks for sharing your code.
0 Kudos