Software Import Wizard

Introduction

VSI software import Wizard, allows users to import C/C++ functions into the VSI dataflow environment. The user can specify multiple source directories, a built-in C/C++ parser will parse all source files in these directories and create a list of functions the user can choose from. Once the user chooses the function associated with the block, the wizard will prefill most of the information “Arguments” section. Figure below shows the screen shot of the Software Import Wizard. The following sections will describe the wizard and each field in greater detail.

../_images/import_C_C++_code_03.pngalt text

Top Level Tab

Source Directory:

The Source directories can be selected by “Browsing” or by entering a comma separated list of directories. A built-in “clang” parser is invoked every time the directory field changes. All files C/C++ files in the directory list are parsed by the built-in parser and a function list is created. The label changes to red (“Top Level”) if the parser encounters an error, correct the parse error to continue. The built-in parser can be run from the command line to determine the cause of the error. To run the parser from the command line, use the following command:

*$(VSI_INSTALL)/<HOST>/bin/vsi_clang \< source_files\> [-I \< include_dir\>]

< HOST> = linux.x86_64 | windows.x86_64

–help* will list the available options.

By default the parser will add the “Vivado HLS Include” path to the include directory path; all other include files are assumed to be present in the directory list provided. The source files from these directories will be copied to the project directory, unless vsi::src_link_files is called from the TCL console, in which case a “soft link” will be created from the project directory to the source directories. The option set by vsi::src_link_files is persistent for a given project it can be switched back by the command vsi::src_copy_files.

C/C++ Function Name:

This dropdown list is created by the built-in parser. Choose the function associated with the block. By default the function is expected to be non-blocking. The VSI compiler will generate a wrapper function which will call the chosen function; the input arguments are updated by the vsi::runtime environment before the function is called, the output arguments are read and send to the input of the connected function by the vsi::runtime when the function returns. The vsi::runtime supports other execution models as well. Complex systems sometimes require functions to have feedback/dependency between each other; i.e. a function can only proceed depending on the state of another function. This can be achieved by using Alt-hls::stream or vsi::device as argument types. Please refer to section hls::stream and vsi::device for more details on these execution models.

Number of Parameters:

This field is automatically updated when the function is chosen from the drop-down list and represents the number of arguments the function has. The maximum number of arguments allowed is 16 ( 8 for versions 2016.4 and earlier).

Allocate on Local Stack:

The vsi:runtime will create a wrapper function which calls the C/C++ function specified in the “C/C++ Function Name” field. The wrapper function allocates some local variables to process the inputs and outputs of the functions. By default these variables will be allocated on the stack, on some target architectures (such as Cortex-R5) running real-time operating systems, the thread stack is limited; by unchecking this box the user can force the runtime to a declare the local variable as “static” which will cause them to be allocated on the global memory area.

Thread Allocation:

The vsi::runtime will execute a function on its caller’s thread by default. It will create a separate thread for a function block, if

  • “Dedicated Thread” is chosen

  • No “Arguments” are marked as “Trigger” in the Argument Tab

Execution Criterion:

vsi::runtime will execute a function if any input argument marked as “trigger” changes. The runtime can also execute a block based on a timer by choosing “Timer Expiry”. The runtime will create a timer which will execute the function every “Execution Timer” nano-seconds. The runtime will keep track of the amount of time spent by the function itself and will adjust the timer to make sure the function is executed as close to the “Execution Timer” value as possible.

Execution Timer (nS):

This field is appeared when the “Execution Criterion” is specified as “Timer”, and specifies the interval for executing the given function.

../_images/Execution_Timer.pngalt text

Arguments Section

Each argument of the function chosen in “C/C++ Function name” will be exposed as an interface of the “block” . This “section” allows the user to specify details about the interface that are not inferred by the built-in parser. Some fields have default values populated by the parser which the user can override. Figure below shows the Screen shot of the Argument section, the number of rows in the argument section is determined by the “Number of Parameters” in the Selected Function.

../_images/software_import_wizard_argument.pngalt text

C/C++ HLS Name:

This field is automatically updated when the function is picked in the “Selected Function” and is the name of the argument.

C/C++ HLS Type:

This filed is automatically updated when the function is picked in the “Selected Function” and is the type of the argument. The two type hls::stream and vsi::device have special handling .

Execution Trigger:

The function is executed whenever data arrives on this “Input” interface. See “Type” dropdown list for more details.

Direction:

The choices as a) Input b) Output or c) Inout .

Variable Length:

Software Context : This is used only when the direction is Input and Type is an Array. Hardware Context: This is used only when the direction is Input and Access Type is Sequential.

Access Type:

The access type will generate different interfaces depending on the type of Context. The following table shows the interfaces generated for the different access types.

Context Access Type Interface Generated
Software Sequential Unidirectional Streaming
Random Unidirectional Streaming
Memory AXI Memory Mapped (can only be connected to memory interfaces in Hardware Context). See vsi::device class for more details.
Control AXI Lite Memory Mapped can only be connected to AXI Lite memory interfaces in Hardware Context). See vsi::device class for more details.
Hardware Sequential Unidirectional Streaming
Random Block Ram Interface
Memory AXI Memory Mapped (can only be connected to memory interfaces in Hardware Context).
Control AXI Lite Memory Mapped can only be connected to AXI Lite memory interfaces in Hardware Context).

The Sequential Vs Random access is important when the block resides in the Hardware Context. Sequential access promises the Hardware Synthesis (Vivado HLS) that the function will always access the argument (Array / Pointer) in a sequential manner and is converted to an AXI Streaming interface.

Array / Max packet size (Bytes):

This field is auto filled when the function is picked in the “Selected function” and represents the size of the buffer that will be allocated in the wrapper function for this argument. For “Pointer” type this field is initialized to -1, since the compiler cannot determine the amount of storage to allocate for this argument. It is important to specify the maximum size of the buffer to be allocated, for “pointers” this value will be used to allocate dynamic storage in the runtime, a value of -1 will cause a runtime failure. This field is not used when the “Type” is “Reference”

Type:

This field is auto filled by the parser when the function is picked in the “Selected function” and represents the storage allocation attribute of the “C/C++ Type” . The choices are a) Array b) Pointer c) Reference d)Interupt e)Value. This attribute along with the C/C++ Type is used by the VSI system compiler to generate the wrapper function for both Software & Hardware . The following table describes the behavior during runtime in a Software Context depending on the Type chosen.

Type Direction Wrapper Action
Array Input/ Inout [Execution Trigger && !Variable Length] A local array of C/C++ Type will be allocated , the wrapper will accumulate input into the array . The user function will be called only when enough data has been received to fill the full array
Input / Inout [Execution Trigger & Variable Length] A local array of C/C++ Type . When new data arrives on this input, the wrapper function will copy the data into the local variable and call the user function.
Input [!Execution Trigger] A local array C/C++ Type, When new data arrives on this interface the data is copied into the array. If more data arrives before the function is executed, the old data will be overwritten.
Output / Inout Data is copied from the output Array and sent to the input of the block that it is connected to.
Pointer It is chosen when the argument is a pointer in C/C++ code. Behaves the same way as Array. Note it is important to specify the Max Size of the buffer to be allocated.
Reference It is chosen when the argument is a reference in C/C++ code. Behaves the same as a pointer
Interupt Currently not supported
Value Input / Output It is chosen when the argument is basic type in C/C++ code such as int

Buffer Depth:

This field is used when the block is placed in the Hardware Context and the access type is “Sequential”. The VSI System Compiler will generate a FIFO of the given depth for each of the interfaces that has value > 0 associated with it.

Sideband Attributes:

The hls::stream Class can be used to describe an AXI Streaming interface in software.


template<int D>
struct ap_axis_dkt {
	ap_uint<D> data;
	ap_uint<1> last;
	ap_uint<D/8> keep;
	ap_uint<1> id;
};
hls::stream<ap_axis_dkt<32> > in;

The above example shows an AXI Streaming interface with sideband signals of ID, LAST & KEEP. The sideband signals will be listed in this entry. When such an interface crosses the boundary between a Hardware & Software context, the VSI system compiler generates code to try to preserve the sideband signals across the interface, with some restrictions.

  • ID – is recognized in the first “beat” of the transfer, the ID will remain the same for the rest of the packet.

  • KEEP – attribute is preserved only on the last beat of the transfer. Both these attributes require the “LAST” attribute to be present.

HLS Parameters

Information in this block is used to generate the Vivado HLS project when the block is placed in a Hardware Context.

Clock Frequency in HZ:

This parameter will be passed to the Vivado HLS project as the requested timing.

Bind Effort:

This parameter specifies the effort that the Vivado HLS compiler will make to share resources, “low” means larger design generated, “high” smaller design generated.

Scheduling Effort:

“Low” will generate slower hardware design, “High” will generate faster hardware design.