Use AXI lite interface for setting parameter HLS IP

PYNQ version: Z2
Tool Version: Vivado 2022.1, Vitis HLS 2022.1

Hello,

I have made an IP in Vitis HLS which is connected to other IPs using an AXI stream interface. It is also connected to the PS using an AXI Lite interface, which I use to start and stop the IP.

Capture

For example, I can start the IP by writing 0x81 to the control register in Jupyter Notebook using the PS:

conv_3_ip = overlay.conv_3x3_3_0
conv_3_ip .write(CONTROL_REGISTER, 0x81)

The outputs of the IP depend on the inputs and some parameters, and currently I have hardcoded the parameters in HLS. I would like to be able to set the parameters using de Jupyter Notebook instead of hardcoding them in HLS. Is it possible to do this via the AXI lite interface without adding an additional AXI lite port? If yes, how can I do it?

The code now looks like this:

void conv_3x3_1(stream_in_t &stream_in, stream_out_t &stream_out) {
	#pragma HLS INTERFACE axis port=stream_in
	#pragma HLS INTERFACE axis port=stream_out
	#pragma HLS INTERFACE s_axilite port=return bundle=config

	static ap_uint<8> local_parameter = 50;
 
	//...
}

But, can I do something like this?:

void conv_3x3_1(stream_in_t &stream_in, stream_out_t &stream_out, ap_uint<1> set_parameter, ap_uint<8> parameter) {
	#pragma HLS INTERFACE axis port=stream_in
	#pragma HLS INTERFACE axis port=stream_out
	#pragma HLS INTERFACE s_axilite port=return bundle=config
	#pragma HLS INTERFACE s_axilite port=set_parameters bundle=config
	#pragma HLS INTERFACE s_axilite port=parameters bundle=config
	
	static ap_uint<8> local_parameter = 0;
	
	if (set_parameters == 1) {
		local_parameter = parameter;
	}
 
	//...
}

And how would I have to set the parameter using the Jupyter Notebook on the PS?

2 Likes

You would bundle the ports into the same interface as you have done.
Have you built your HLS IP? If yes, then search for a *_hw.h file in your HLS project directory. This should show the register offsets to access the parameters for your function.

You may also be able to use the register_map feature in PYNQ to discover the registers/offsets: example video of register map here: Using the PYNQ 'register map' functionality - YouTube

Cathal

1 Like

I am also wondering how to reload the arguments (in a AXI-lite register) while the AXI stream is running. I have tried several methods and it seems to me that this is impossible. The arguments in the AXI lite register are fixed once the IP core starts, and you can only update them after the IP core stops.

If anyone has figured out a solution, please kindly update in this thread. Thanks!

Hi @godfly

This is correct if the mode of operation is

You may be able to achieve what you are looking for by using ap_ctrl_none
https://docs.amd.com/r/en-US/ug1399-vitis-hls/Block-Level-Control-Protocols

For more help, you may be better of in the Xilinx forums

Mario

Thanks! I still have a question regarding the software control.

If I were to update the arguments using ap_none_ctrl, and if I understand correctly, the synthesized ports of the arguments would look like in1 and in2 in the following picture from Interfaces for Vivado IP Flow - UG1399:

What, then, would be the best way, on the software side, to update these arguments? Should I use GPIO? Or should I use some other IP cores with AXI lite registers and connect them to the ap_ctrl_none ports for the arguments to be updated (say, in1 and in2)?

Hi @godfly,

I meant applying ap_none_ctrl to the s_axilite interface. This will make your kernel free running.

Mario