UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor jamesh
Visitor
377 Views
Registered: ‎09-12-2018

Manually loading a bitstream from standalone software

Hello, I'm working with a Xilinx Zynq UltraScale+ with standalone software in the 2017.2 SDK. I'd like to be able to program the PL with a specific bit file on the SD card from software after the board is already booted.

First I set aside some memory in lscript.ld to hold the bit file:

MEMORY
{
   psu_ddr_0_MEM_0 : ORIGIN = 0x0, LENGTH = 0x7E000000
   psu_ddr_1_MEM_0 : ORIGIN = 0x800000000, LENGTH = 0x80000000
   psu_ocm_ram_0_MEM_0 : ORIGIN = 0xFFFC0000, LENGTH = 0x40000
   psu_qspi_linear_0_MEM_0 : ORIGIN = 0xC0000000, LENGTH = 0x20000000
   bit_file_BASEREG  : ORIGIN = 0x7E000000, LENGTH = 0x2000000
}
.bit_file : {
   . = ALIGN(32);
   __bit_file_start = .;
   *(.bit_file)
   __bit_file_end = .;
} > bit_file_BASEREG

And create a pointer to that piece of memory:

uint8_t bit_file_buffer[BIT_FILE_BUF_SIZE] __attribute__((section(".bit_file")));

And here's the code used to load the bit file into memory and program the PL:

int load_bit_file(const char *file_name, uint32_t *file_size)
{
	FIL fil;
	FRESULT res = f_open(&fil, file_name, FA_READ);
	if (res != FR_OK)
	{
		xil_printf("Unable to open %s for reading\n\r", file_name);
		return -1;
	}
	res = f_read(&fil, bit_file_buffer, BIT_FILE_BUF_SIZE, file_size);
	if (res != FR_OK)
	{
		xil_printf("Unable to load bit file. Error: %d\r\n", res);
		return -1;
	}
	else
	{
		xil_printf("Loaded %d bytes of %s into address %lx\r\n", *file_size, file_name, (uint64_t)bit_file_buffer);
	}
	return 0;
}

int flash_fpga(const char *file_name)
{
	uint32_t file_size;
	if (load_bit_file(file_name, &file_size))
	{
		return -1;
	}

	uint64_t addr = (uint64_t)bit_file_buffer;
	if (XFpga_PL_BitSream_Load((uint32_t)(addr>>32), (uint32_t)addr, file_size/4, 0) != XFPGA_SUCCESS)
	{
		print("FPGA programming failure\r\n");
	}
	else
	{
		print("Successfully programmed FPGA\r\n");
	}

	return 0;
}

However, when I run this with a .bit file, XFpga_Bitsream_Load throws an error and prints "FPGA fail to get the done status".

I know the .bit file is good because it's what I pass to bootgen to create a functioning boot image. Am I misunderstanding the XFpga_Bitsream_Load function?

0 Kudos
4 Replies
Moderator
Moderator
335 Views
Registered: ‎06-27-2017

Re: Manually loading a bitstream from standalone software

@jamesh,

 

Did you check the memory content between address of your function parse and original(copy to some other location)?

Best Regards
Kranthi
--------------------------
Don't forget to reply, kudo, and accept as solution.
0 Kudos
Moderator
Moderator
321 Views
Registered: ‎09-12-2007

Re: Manually loading a bitstream from standalone software

0 Kudos
Visitor jamesh
Visitor
298 Views
Registered: ‎09-12-2018

Re: Manually loading a bitstream from standalone software

I tried the standalone flow, and the example code worked for me.

I then tried copying my .bit file into the area of memory defined by XFPGA_BASE_ADDRESS in xfpga_config.h, as this is where the example code pulls it's FPGA image. This totally wrecked my code, I'm guessing because the 25MB .bit file is overwriting all sorts of important stuff.

To me this implies that the data originally located at XFPGA_BASE_ADDRESS is different from the data in my .bit file. Does bootgen do some transformation on this?

0 Kudos
Visitor jamesh
Visitor
297 Views
Registered: ‎09-12-2018

Re: Manually loading a bitstream from standalone software

I just did a comparison, and all the bytes match up from the on-chip memory and the file on the SD card.

0 Kudos