C-Callable IP Libraries
This section describes how to create a C-Callable IP library for IP blocks written in a hardware description language like VHDL or Verilog. User applications can statically link with such libraries using theSDSoC™system compiler, and the IP blocks are instantiated into the generated hardware system. Using theSDx™IDE and its command line equivalents are shown.
SDSoCapplications can use C-Callable IP libraries to access packaged IP blocks written in a hardware description language (HDL) such as VHDL or Verilog or with a high-level synthesis (HLS) tool likeVivado®HLS. At times, hardware specific optimizations or micro-architectures are easier to implement through an HDL and can be delivered encapsulated within a C-Callable library.
Using a C-Callable IP library provides both the design reuse flexibility of a software library and the performance gain of optimized hardware IP blocks. With a bottom-up approach individual IP blocks can be designed, implemented, and tested prior to being placed into a C-callable library for broader use. The library of hardware-accelerated functions allows a means to insulate hardware and software development teams from low-level implementation details while still ensuring that both teams are cognizant of the functional interfaces.
Creating C-Callable IP Libraries
TheSDx™installation contains examples of C-Callable IP in the
TheSDxIDE's Library Project flow is used to create a C-Callable IP library with foundational support from thesdx_packutility. A description of thesdx_packcommand line arguments can be found in theSDx Command and Utility Reference Guide(UG1279). For inspecting interfaces withinVivado-packaged IP,sdx_packprovides the capability to query IP settings including their hardware interfaces. TheSDxIDE uses this feature to populate menu selections with interfaces and pull-down choices relevant to the IP being transformed into a C-Callable IP library.
A procedure for creating a C-Callable IP library using theaxis_arraycopyexample for a zcu102 platform is described below. Theaxis_arraycopyexample contains theVivado-packaged IP and the files used to create thelibarraycopy.alibrary. Thearraycopy.hppheader file contains the software function declarations associated with the hardware functionality provided in the packaged IP. Thecomponent.xmlcontains the meta-data used by theSDxIDE and the underlyingsdx_pack
tool to build the library.
The following steps are necessary to create the C-Callable IP library with theSDxIDE:
- Create a C-Callable IP Library project.
- Each library is created for a specific
device_family
,cpu_type
, andOS_type
tuple.
- Each library is created for a specific
- Import source files from the
/samples/rtl directory.- Import both the header file and the packaged IP.
- Identify the header file (.hpp) and the IP meta-data file (component.xml) to use as inputs to build the C-Callable IP library.
- Show how to customize the IP.
- Indicate how the arguments of each function in the C-Callable IP library maps to the hardware IP.
The following tables guide you on how to complete theSDxdialogs.
- The top row of each table contains theSDxIDE menu selection to begin each task.
- TheDialogcolumn lists the names of the subsequent dialog boxes that open.
- SelectionandActioncolumns indicate how to fill out the dialog boxes to complete the task.
SDx Library Project
Begin by launching theSDxIDE and specifying a workspace (for example,sdx_workspace) to create a Library project ( ).
The project name becomes the name of the library created by concatenating the prefixliband the.asuffix (lib
Dialog | Selection or Field Name | Action |
---|---|---|
Project Type | Application | ClickNext |
Create a NewSDxProject | Project name: | arraycopy |
Use default location | Check-mark | |
ClickNext | ||
Accelerated Library Type | Type: | C-Callable Library |
Platform | Name | zcu102 |
ClickNext | ||
System Configuration | System configuration: | A53_Linux |
Runtime: | C/C++ | |
Domain: | a53_linux | |
(pre-set) | CPU: | cortex-a53 |
(pre-set) | OS: | linux |
Linux Root File System: | Leave unchecked | |
ClickNext | ||
Templates | Empty Application | ClickFinish |
Import Sources Dialog Options
The following table shows the menu selection for importing sources.
Dialog | Selection or Field Name | Action |
---|---|---|
File system | From directory: | Browse toaxis_arraycopydirectory insamples/rtl |
ClickOK | ||
Files:src/arraycopy.hpp | Check-marked | |
Directory:ip | Check-marked | |
Into folder: | arraycopy/src | |
ClickFinish |
Add IP Customizations
In the IP Customizations window, clickAdd IP Customizations(file icon with stylized "h"). The following figure and table show how to add IP customization.
Dialog | Selection or Field Name | Action |
---|---|---|
Add IP Customizations | Header File: | ClickSelect |
Files: | Selectarraycopy.hpp | |
Qualifier: | Selectsrc/src/arraycopy.hpp | |
ClickOK | ||
IP Path: | ClickSelect | |
Files: | Selectcomponent.xml | |
Qualifier: | Selectsrc/ip/component.xml | |
ClickOK | ||
Accelerator control: | Protocol:ap_ctrl_hs | |
Port:s_axi_lite | ||
Offset:0 | ||
Primary Clock:ap_clk |
10.0 | |
Derived Clock: | (no change) | |
IP Parameters | (no change) | |
ClickOK |
Add Function Mapping
Thisaxis_arraycopyexample uses the contents of the providedsamples/rtl/axis_arraycopy/src/Makefileto complete the dialog box option.
Thecomponent.xmland, if provided, theregister_map.txtfiles associated with the IP block can also be queried for information on the how the function arguments map to the hardware.
In the IP Customizations window, clickAdd Function Mapping("+" icon) shown in the figure and table.
Dialog | Selection or Field Name | Action |
---|---|---|
Add Function Mapping | Function name: | Click"+"icon on the right-side |
Selectarraycopy | ||
ClickOK | ||
Arguments and Function Return mapped toAXILite Interface |
ClickAdd Function Argument Map("+" icon) above the table for this interface type | |
Argument(Click within field to expose pull-down menu) | M | |
AXILite Interface (Click within field to expose pull-down menu) |
s_axi_lite | |
Direction(Click within field to expose pull-down menu) | IN | |
Register Info(Click within field to expose pull-down menu) | M, at offset16 | |
Array Arguments mapped toAXIS Interface |
ClickAdd Function Argument Map("+" icon) above the table for this interface type | |
Argument(Click within field to expose pull-down menu) | A | |
AXIS Interface (Click within field to expose pull-down menu) |
A | |
Direction(Click within field to expose pull-down menu) | IN | |
Array Arguments mapped toAXIS interface |
ClickAdd Function Argument Map("+" icon) above the table for this interface type | |
Argument(Click within field to expose pull-down menu) | B | |
AXIS Interface (Click within field to expose pull-down menu) |
B | |
Direction(Click within field to expose pull-down menu) | OUT | |
Complete the Add Function Mapping dialog box | ClickOK |
Building the C-Callable IP Project
To build the project, the C-Callable IP library is generated and placed in the build output directory of the application (for example, theReleasedirectory) with the namelib
In addition to theSDxIDE method of creating a C-Callable IP library, a command line method that directly invokes thesdx_pack
tool is available. The equivalentsdx_pack
command to match the actions taken with theSDxIDE for theaxis_arraycopy
example is:
sdx_pack -header arraycopy.hpp -lib libarraycopy.a \ -func arraycopy -map A=A:in -map B=B:out -map M=s_axi_lite:in:16 -func-end \ -ip ../ip/component.xml -control ap_ctrl_hs=s_axi_lite:0 \ -primary-clk ap_clk=10.0 -target-family zynquplus \ -target-cpu cortex-a53 -target-os linux \ -verbose
-func
and
-func-end
options of the
sdx_pack
call.
Multi-Function Accelerator Libraries
Theaxis_arraycopyexample is a library with a single accelerator function. Other examples, in particular the ones that begin with themfa_prefix are multi-function accelerator (MFA) libraries where more than one function is mapped onto one IP block. Below is thesdx_pack
command for themfa_scalar_128_noneexample that generates thelibmfa.a.
The C-Callable IP library contains eight functions and is shown in the following code example. This accelerator library uses control protocolnone
, indicating that the user explicitly controls the IP. This MFA example also demonstrates 128-bit scalar function arguments that map toAXI4-Liteinterfaces as well as 128-bit array arguments that map to masterAXI4-Streaminterfaces.
sdx_pack -header mfa.hpp -I inc -lib libmfa.a \ -func mfa_reset -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_init -map inA=inA:in -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_copy -map outB=outB:out -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_sum -map result=axi_AXILiteS:out:0x2c -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_status -map return=axi_AXILiteS:out:0x10 -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_status2 -map status=s_axi_AXILiteS:out:0x10 -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -func mfa_result -map result=s_axi_AXILiteS:out:0x2c -func-end \ -func mfa_stop -map inst=s_axi_AXILiteS:in:0x40 -func-end \ -ip ../ip/component.xml -control none \ -add-ip-repo ../dummy_ip \ -add-ip-repo ../dummy_ip_repo \ -primary-clk ap_clk=10.0 \ -target-family zynquplus -target-cpu cortex-a53 -target-os linux -verbose
Another example of an MFA type of C-Callable library is themfa_scalar_axiaccelerator. This accelerator library uses anap_ctrl_hs
control protocol and shows the use of scalar function arguments that map toAXI4-Liteinterfaces as well as array arguments that map to masterAXI4interfaces.
sdx_pack -header mfa.hpp -I inc -lib libmfa.a \ -func mfa_reset -map status=s_axi_AXILiteS:out:0x20 -map inst=s_axi_AXILiteS:in:0x34 -func-end \ -func mfa_init -map inA=s_axi_AXILiteS:in:0x10,m_axi_inA:in -map status=s_axi_AXILiteS:out:0x20 \ -map inst=s_axi_AXILiteS:in:0x34 -func-end \ -func mfa_copy -map outB=s_axi_AXILiteS:in:0x18,m_axi_outB:out -map status=s_axi_AXILiteS:out:0x20 \ -map inst=s_axi_AXILiteS:in:0x34 -func-end \ -func mfa_sum -map result=s_axi_AXILiteS:out:0x28 -map status=s_axi_AXILiteS:out:0x20 \ -map inst=s_axi_AXILiteS:in:0x34 -func-end \ -func mfa_status -map status=s_axi_AXILiteS:out:0x20 -func-end \ -func mfa_stop -map status=s_axi_AXILiteS:out:0x20 -map inst=s_axi_AXILiteS:in:0x34 -func-end \ -ip ../ip/component.xml -control AXI=s_axi_AXILiteS:0x0 \ -primary-clk ap_clk=10.0 \ -target-family zynquplus -target-cpu cortex-a53 -target-os linux -verbose
A register map showing the bit-level definition of theAXI4-Litecontrol protocol signals used in themfa_scalar_axiexample is provided in themfa_scalar_axi/ip/register_map.txtfile and excerpted below. In general, IP register mapping information is provided by the IP developer.
// ============================================================== // File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC // Version: 2018.3 // Copyright (C) 1986-2018 Xilinx, Inc. All Rights Reserved. // // ============================================================== // AXILiteS // 0x00 : Control signals // bit 0 - ap_start (Read/Write/COH) // bit 1 - ap_done (Read/COR) // bit 2 - ap_idle (Read) // bit 3 - ap_ready (Read) // bit 7 - auto_restart (Read/Write) // others - reserved // 0x04 : Global Interrupt Enable Register // bit 0 - Global Interrupt Enable (Read/Write) // others - reserved // 0x08 : IP Interrupt Enable Register (Read/Write) // bit 0 - Channel 0 (ap_done) // bit 1 - Channel 1 (ap_ready) // others - reserved // 0x0c : IP Interrupt Status Register (Read/TOW) // bit 0 - Channel 0 (ap_done) // bit 1 - Channel 1 (ap_ready) // others - reserved // 0x10 : Data signal of inA_offset // bit 31~0 - inA_offset[31:0] (Read/Write) // 0x14 : reserved // 0x18 : Data signal of outB_offset // bit 31~0 - outB_offset[31:0] (Read/Write) // 0x1c : reserved // 0x20 : Data signal of status // bit 31~0 - status[31:0] (Read) // 0x24 : Control signal of status // bit 0 - status_ap_vld (Read/COR) // others - reserved // 0x28 : Data signal of result // bit 31~0 - result[31:0] (Read) // 0x2c : Data signal of result // bit 31~0 - result[63:32] (Read) // 0x30 : Control signal of result // bit 0 - result_ap_vld (Read/COR) // others - reserved // 0x34 : Data signal of inst // bit 31~0 - inst[31:0] (Read/Write) // 0x38 : reserved // (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
Themfa_firC-Callable IP library example highlights instantiating IP parameters, usingAXI4-Streaminterfaces, a 24-bit data type, and a control protocol selection ofnone.
ibfir.a: fir.hpp sdx_pack -header fir.hpp -lib libfir.a \ -func fir -map X=S_AXIS_DATA:in -map Y=M_AXIS_DATA:out -func-end \ -func fir_reload -map H=S_AXIS_RELOAD:in -func-end \ -func fir_config -map H=S_AXIS_CONFIG:in -func-end \ -ip ../ip/fir_compiler_v7_2/component.xml -control none \ -param DATA_Has_TLAST="Packet_Framing" \ -param M_DATA_Has_TREADY="true" \ -param Coefficient_Width="8" \ -param Data_Width="8" \ -param Quantization="Integer_Coefficients" \ -param Output_Rounding_Mode="Full_Precision" \ -param Coefficient_Reload="true" \ -param Coefficient_Structure=Non_Symmetric \ -primary-clk aclk_intf=10.0 \ -target-family zynquplus -target-cpu cortex-a53 -target-os linux -verbose
Considerations for C-Callable IP Libraries
- Function arguments of
TYPE *a
orTYPE &a
are interpreted as anOUTPUT
scalar. - Arrays must be declared as
TYPE a[N]
orTYPE a[]
. - Function return type can only be a scalar in the format of
TYPE: TYPE*
orTYPE&
are not allowed. - C-Callable IP library header files cannot have SDS pragmas that use
MACRO
as parameters:#pragma sds data copy (A[0:SIZE])
is not allowed whenSIZE
is a macro (for example,#define SIZE 16
). - Overlapped function calls of multi-function accelerators (MFAs) are not allowed, as there is only one IP instance in the hardware; therefore,
async
pragmas around MFA functions are very risky and not recommended unless there is no chance of overlapping during runtime. - Argument sizes must match between the software declared argument and the hardware port pair:
/Release/reports/sdx_pack.html report file can be used to double-check if the library implemented the expected argument sizes, offsets, and bus interfaces. - This supports up to oneAXI4-Liteinterface per top-level IP.
- For C-Callable functions, all pragmas must be applied when building the library using
sdx_pack
. Any pragmas added into the header file after the library is already built are ignored by the tool.
sdx_pack Command
The following are examples of thesdx_pack
command:
sdx_pack -header -ip
[-param ="value"] [configuration options]
The following table provides further details on thesdx_pack
tool.
Option | Description |
---|---|
-header header.h/.hpp |
(required) Header file (.h, .hpp) with function prototypes.sdx_pack generates C++ style library for a.hppfile and a C-style library for a.hfile.Only one top-level header file is allowed per library. The top-level header can include other header files, using the-I option. |
-ip component.xml |
(required) Path toVivadopackaged IP. Only one top-level IP per library. The top-level IP can invoke other IP blocks, using the-add-ip-repo option. |
-control protocol [=port [:offset]] |
(required) IP control protocol options:
|
-func function_name -map swName= hwNAME:direction[:offset[aximm_name:direction]] -func-end |
(required) Specify a list of C-Callable IP functions. Each function is listed between a The
|
-param name="value" |
IP parameter name-value pairs to instantiate IP parameters. Use one-param option per pair. |
-lib libname |
Use specifiedlibname for naming the generated library. By defaultlib header.ais used. |
-I path |
If the file named with the-header option includes other files, this option specifies the path to the additionally included files. Multiple-I options can be used. For easier library distribution, place all include files into a single directory. |
-add-ip-repo path |
Add all IP found in the listed repository into the library. Although multiple-add-ip-repo options can be used to specify multiple paths.Xilinxrecommends to place all required IP into a single directory and use a single |
-primary-clk clk_interface=min_clk_period |
Specify the primary clock interface and its minimum clock period in nanoseconds. |
-derived-clk clk_interface=multiplier:divisor |
Specify a phase-aligned derived clock interface and its multiplier and divisor in units of integers. Only two phase-aligned clocks are supported. |
-target-family device_family |
The target device family supported by the IP (for example,zynq (default),zynquplus ). |
-target-cpu cpu_type |
Specify target CPU:
|
-target-os name |
Specify target OS:
|
-query-target type |
Query one of: supported device families, cpu types, or OS type for the IP [family, cpu, os ] |
-query-interface type |
Query interfaces and parameters of the IP. Multiple query types supported [all, aximm, axilite, axis, clock, control, param, misc ]
Note:This requires that the IP has packaged all necessary information needed by the query.
|
-o output.json |
User-specified JSON file to save query results. |
-verbose |
Print verbose output toSTDOUT. |
-version |
Print thesdx_pack version information toSTDOUT. |
-h, -help, --help |
Displaysdx_pack option usage and descriptions. |
Here is an example of the code:
sdx_pack -header arraycopy.hpp -lib libarraycopy.a \ -func arraycopy -map A=A:in -map B=B:out \ -map M=s_axi_lite:in:16 -func-end \ -ip ../ip/component.xml -control AXI=s_axi_lite:0 \ -target-family zynquplus -target-cpu cortex-a53 -target-os standalone \ -verbose
Where:
- arraycopy.hppspecifies the header file defining the function prototype for the
arraycopy
function. - component.xmlof the IP generates the packagedVivadoIP forSDx.
-control
specifies the IP control protocol.–map
specifies the mapping of an argument from the software function to a port on theVivadoIP. Notice the option is used three times in the example above to map function argumentsA
,B
, andM
to IP ports.- The
–target-os
option specifies the target operating system.
Thesdx_pack
utility generates a C-Callable IP library to match the name in the-lib
option,libarraycopy.ain this case.
Using C-Callable IP Libraries
After generating the C-Callable library, create a newSDxApplication project to use the library. Continuing with the example of theaxis_arraycopy
C-Callable IP library built in the previous section, use the generated library (libarraycopy.a) from the library build's Release directory. The result of building the Application project is an executable file (ELF) that is linked with the C-Callable IP Library.
- Create anSDxapplication project to output an executable file. Click .
Note:The tuple consisting of
device_family
,cpu_type
, andos_type
must match that of the C-Callable IP library.Table 6.SDxApplication Project Dialog Box Selection or Field Name Action Project Type Application ClickNext Create a NewSDxProject Project name: app_arraycopy Use default location Check-marked ClickNext Platform Name zcu102
ClickNext System Configuration System configuration: A53_Linux Runtime: C/C++ Domain: a53_linux (pre-set) CPU: cortex-a53 (pre-set) OS: linux Linux Root File System: Unchecked ClickNext Templates Empty Application ClickFinish - Import the function declarations header file (.hpp) common to both the library and the application. In the Project Explorer window, right-clickapp_arraycopyand selectImport Sources.
Table 7.Select Import Sources Dialog Selection or Field Name Action File system From directory: Browse toaxis_arraycopy/src directory in /samples/rtl .ClickOK Files: arraycopy.hpp Check-marked Into folder: app_arraycopy/src ClickFinish - Open the Importing Sources dialog box again to get the example main application code from the
/samples/rtl directory. In the Project Explorer window, right-clickapp_arraycopyand selectImport Sources.Table 8.Select Import Sources Dialog Selection or Field Name Action File system From directory: Browse to theaxis_arraycopy/appdirectory in /samples/rtl ClickOK Files: main.cpp Check-marked Into folder: app_arraycopy/src ClickFinish app_arraycopy
application have been imported, update theC/C++ Build Settingsto have thesds++
linker use thearraycopy.aC-Callable IP library when building the application. - Update theC/C++ Build Settingsin the Project Explorer window, right-clickapp_arraycopyand selectC/C++ Build Settingsas shown in the table.
Table 9.C/C++ Build Settings Dialog Selection or Field Name Action SDS++ Linker SelectLibraries ClickAddsymbol (with "+" icon) in the Libraries (-l) window Libraries(-l) arraycopy ClickOK ClickAddsymbol (with "+" icon) in the Library search path (-L) window ClickWorkspace Folder: Navigate to and selectarraycopy/Release ClickOK (pre-set) Directory: ${workspace_loc:/arraycopy/Release} ClickOK ClickApply and Close
To create the application, you can use the Assistant window to build theapp_arraycopyapplication.
- In the Assistant window underapp_arraycopy[SDSoC], right-clickDebug[Hardware]and selectBuild. The Console window shows the build progression including the
sds++
system compiler invocation. - After the application successfully builds the target executable file (app_arraycopy.elf), the Assistant window populates with aData Motion NetworkReport, theCompilation Log, and anSD Card Imagemenu. Through theSD Card Imagemenu, the contents of the generated (sd_card) files directory is available to view using the Project Explorer, a file browser, or a command shell window.
- When the build completes, you can write the contents of the generatedsd_carddirectory to the root of a FAT32-formatted SD card and boot and run theapp_arraycopy.elfapplication on a ZCU102 board. Thesd_carddirectory includes aREADME.txtfor boot setup instructions, a bootableBOOT.BINfile, and theimage.ubfile used to boot Linux.
TheSDxIDE builds the application with thesds++
system compiler using the C-callable library and the application code. The main application is compiled to produce an object file and then it is linked with the C-callable library (arraycopy).
The following examples show the issued commands.
Compilation ofmain.cpp:
sds++ -Wall -O0 -g -I../src -c -fmessage-length=0 -MTsrc/main.o -MMD -MP -MFsrc/main.d \ -MTsrc/main.o -o src/main.o ../src/main.cpp \ -sds-sys-config a53_linux -sds-proc a53_linux -sds-pf zcu102
Linkingmain.owitharraycopylibrary to produce executable applicationapp_arraycopy.elf:
sds++ -L --remote_ip_cache ../ip_cache \ -o app_arraycopy.elf ./src/main.o -larraycopy -dmclkid 1 \ -sds-sys-config a53_linux -sds-proc a53_linux -sds-pf zcu102