Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Currently we have used HLS on its own. In this practical we will actually implement the HLS component as part of an FPGA design. First we will learn how to do this, and then we will create some hardware to solve some problems.

...

Info

Connection Automation issues

If you have issues with the AXI buses generated using connection automation (i.e. if they differ from the structure above), try deleting all AXI Interconnect blocks and running it again. If in doubt, ask a demonstrator.

The general principle is that your Zynq block's M_AXI should be traceable to all S_AXIs on your IP cores, and the IP core's M_AXI should be traceable to the S_AXI_HP0 on the Zynq block.

Using the IP in Vitis

When HLS exported our IP it helpfully autogenerated us a software driver. However we need to tell Vitis where to find this driver.

...

As you can see, your component can be started with XToplevel_Start and XToplevel_IsDone tells you when it is complete. XToplevel_Set_ram tells the HLS component where our shared memory is located in main memory. This allows HLS to read and write as if RAM starts at 0, but it will actually be pointing at our shared memory. Don't forget to set the RAM offset or your HLS component will be writing over random bits of memory!

Info

AXI bus problems

If your software hangs when trying to write to registers in your HLS component, double-check that the AXI buses are connected correctly, take your Vitis back to basics. Reexport a new hardware platform, create a new Hello World on it, making sure you can see the output. Check the System has the driver for your IP core, then copy in your code to access the core.

Functions like XToplevel_Get_arg1 and XToplevel_Set_arg1 get and set the parameters of the toplevel function. Sometimes these getters and setters may have slightly different names based on how your core uses the arguments. For example, if you only read an input then HLS will generate functions like:

...

Info

The Collatz Conjecture

Take any positive integer n (where n is not 0).
If n is even, divide it by 2 to get n / 2. If n is odd, multiply it by 3 and add 1 to obtain 3n + 1.
Repeat the process indefinitely.
The conjecture is that no matter what number you start with, you will always eventually reach 1.

You will create an HLS component to test the first 1000 integers to verify that if you perform the above steps they all eventually converge to 1. You will output the number of steps that each number takes to get to 1 in a shared array.

...

toplevel.cpp
Code Block
languagecpp
#include "toplevel.h"
#include <string.h> // Required for memcpy()
 
uint32 workingmem[1000];

uint32 toplevel(uint32 *ram, uint32 *arg1, uint32 *arg2, uint32 *arg3, uint32 *arg4) {
	#pragma HLS INTERFACE m_axi port=ram offset=slave bundle=MAXI
	#pragma HLS INTERFACE s_axilite port=arg1 bundle=AXILiteS 
	#pragma HLS INTERFACE s_axilite port=arg2 bundle=AXILiteS 
	#pragma HLS INTERFACE s_axilite port=arg3 bundle=AXILiteS 
	#pragma HLS INTERFACE s_axilite port=arg4 bundle=AXILiteS 
	#pragma HLS INTERFACE s_axilite port=return bundle=AXILiteS 

	//Read in starting values
	memcpy(workingmem, ram, 4000);

	//Calculate the Collatz results. 
	//workingmem[x] = collatz(workingmem[x]);
	//...your code here...

	//Burst copy workingmem to main memory
	memcpy(ram, workingmem, 4000);
	return 0;
}

...