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.

Figure:Create and Use a C-Callable Library

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/samples/rtldirectory. These examples show single-function as well as multi-function accelerator libraries where function arguments are passed as registers, memory references, or AXI streams, which are highlighted (axilite_arraycopy,aximm_arraycopy,axis_arraycopy). The multi-function examples (mfa_fir,mfa_scalar128_none,mfa_scalar_axi) highlight single accelerators with multiple software entry points.

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_packtool to build the library.

The following steps are necessary to create the C-Callable IP library with theSDxIDE:

  1. Create a C-Callable IP Library project.
    • Each library is created for a specificdevice_family,cpu_type, andOS_typetuple.
  2. Import source files from the/samples/rtldirectory.
    • Import both the header file and the packaged IP.
  3. Identify the header file (.hpp) and the IP meta-data file (component.xml) to use as inputs to build the C-Callable IP library.
  4. Show how to customize the IP.
  5. 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 (File>New>SDx Library Project).

The project name becomes the name of the library created by concatenating the prefixliband the.asuffix (lib.a).

Table 1.SDx Library Project
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.

Table 2.Import Sources Dialog Options
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.

Table 3.Add IP Customizations
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.

Table 4.Add Function Mapping
Dialog Selection or Field Name Action
Add Function Mapping Function name: Click"+"icon on the right-side
Selectarraycopy
ClickOK
Arguments and Function Return mapped toAXILiteInterface 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 toAXISInterface 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 toAXISinterface 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.a(libarraycopy.afor this example).

In addition to theSDxIDE method of creating a C-Callable IP library, a command line method that directly invokes thesdx_packtool is available. The equivalentsdx_packcommand to match the actions taken with theSDxIDE for theaxis_arraycopyexample 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
Note:The C-Callable function and its argument map is listed between -funcand -func-endoptions of the sdx_packcall.

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_packcommand 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_hscontrol 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

  1. Function arguments ofTYPE *aorTYPE &aare interpreted as anOUTPUTscalar.
  2. Arrays must be declared asTYPE a[N]orTYPE a[].
  3. Function return type can only be a scalar in the format ofTYPE: TYPE*orTYPE&are not allowed.
  4. C-Callable IP library header files cannot have SDS pragmas that useMACROas parameters:#pragma sds data copy (A[0:SIZE])is not allowed whenSIZEis a macro (for example,#define SIZE 16).
  5. Overlapped function calls of multi-function accelerators (MFAs) are not allowed, as there is only one IP instance in the hardware; therefore,asyncpragmas around MFA functions are very risky and not recommended unless there is no chance of overlapping during runtime.
  6. Argument sizes must match between the software declared argument and the hardware port pair:/Release/reports/sdx_pack.htmlreport file can be used to double-check if the library implemented the expected argument sizes, offsets, and bus interfaces.
  7. This supports up to oneAXI4-Liteinterface per top-level IP.
  8. For C-Callable functions, all pragmas must be applied when building the library usingsdx_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_packcommand:

sdx_pack -header -ip 
[-param ="value"] [configuration options]

The following table provides further details on thesdx_packtool.

Table 5.sdx_pack Command Options
Option Description
-header header.h/.hpp

(required)

Header file (.h, .hpp) with function prototypes.sdx_packgenerates 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-Ioption.
-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-repooption.
-control protocol [=port [:offset]] (required) IP control protocol options:
  • ap_ctrl_hs

    Automatic control protocol based on anAXI4-Litecontrol register, typically at offset0x0(for example:-control ap_ctrl_hs=s_axi_AXILiteS:0)

  • none

    User application explicitly controls the IP (for example-control none)

-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-funcand-func-endoption pair. Function arguments are mapped to each IP port with the-mapoption.

The-mapoption is then used as follows:

  • Scalarsmap onto anAXI4-Liteinterface
    • Map input scalar (for example,int a) with-map a=s_axi_AXILiteS:in:offset
    • Map output scalar (for example:int *a, orint &a) with-map a=s_axi_AXILiteS:out:offset
    • Map function return scalar (return type can only be a scalar) with-map return=s_axi_AXILiteS:out:offset
  • Arraysmap ontoAXI4,AXI4-Stream, orAXI4-Liteinterfaces. The arrays must be one-dimensional (for example,int a[N], orint a[]).
    • Map toAXI4, with-map a=s_axiAXILiteS:in:offset,a_hwName:direction. Not allowed whencontrol=none.

      The first part is mapping to the address and the second part is mapping to the data port.

    • Map toAXI4-Streamwith-map a=a_hwName:direction.
    • Map toAXI4-Litewith-map a=s_axi_AXILiteS:in:offset. Array must be one-dimensional and of constant size.
-param name="value" IP parameter name-value pairs to instantiate IP parameters. Use one-paramoption per pair.
-lib libname Use specifiedlibnamefor naming the generated library. By defaultlib header.ais used.
-I path If the file named with the-headeroption includes other files, this option specifies the path to the additionally included files. Multiple-Ioptions 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-repooptions can be used to specify multiple paths.

Xilinxrecommends to place all required IP into a single directory and use a single-add-ip-repooption.

-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:
  • cortex-a9(default)
  • cortex-a53
  • cortex-r5
  • microblaze
-target-os name Specify target OS:
  • linux(default)
  • standalone(bare-metal)
-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_packversion information toSTDOUT.
-h, -help, --help Displaysdx_packoption 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 thearraycopyfunction.
  • component.xmlof the IP generates the packagedVivadoIP forSDx.
  • -controlspecifies the IP control protocol.
  • –mapspecifies 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, andMto IP ports.
  • The–target-osoption specifies the target operating system.

Thesdx_packutility generates a C-Callable IP library to match the name in the-liboption,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_arraycopyC-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.

  1. Create anSDxapplication project to output an executable file. ClickFile>New>SDx Application Project.
    Note:The tuple consisting of device_family, cpu_type, and os_typemust 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
  2. 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
  3. Open the Importing Sources dialog box again to get the example main application code from the/samples/rtldirectory. 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
    Now that the source files for theapp_arraycopyapplication have been imported, update theC/C++ Build Settingsto have thesds++linker use thearraycopy.aC-Callable IP library when building the application.
  4. 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
    Settings>Tool Settings 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.

  1. In the Assistant window underapp_arraycopy[SDSoC], right-clickDebug[Hardware]and selectBuild. The Console window shows the build progression including thesds++system compiler invocation.
  2. 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.
  3. 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