We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 64980

SDK - How to use the HSI to create a custom driver


I have created a custom IP in the Vivado IP packager.

However, I would like to create a custom driver.

How can I achieve this?


This Answer Record will discuss how to use the HSI tool to create a custom driver to populate the xparameters.h file in SDK.


Step 1: Create the IP in IP packager.

Here, an AXILite IP was created with the interrupt enabled. 

This IP was then added to the Block Design in Vivado IP Integrator.

The BD can be seen below. 

The custom IP; myip_0 can be see here.

Step 2: Explore the HW design using HSI

When exporting to SDK, a HDF file will be created. 

This HDF file can be opened in HSI, and the hardware can be explored.

In SDK, launch the SDK shell, then launch HSI, and navigate to the HW_platform (this is where the HDF resides):

Open the HW design in HSI using the command below:

open_hw_design system.hdf

You can see all of the IP in the design using the command below:

get_cells *

You can see all the properties of an IP (in this case, myip_0) using the command below:

list_property [get_cells myip_0]

You can now list all of the pins on an IP (in this case, myip_0) using the command below:

get_pins -of_objects [get_cells myip_0]

You can see all clock pins on an IP (in this case, myip_0) using the command below:

get_pins -of_objects [get_cells myip_0] -filter TYPE==clk

You can view the properties of a pin using the command below:

list_property [get_pins <pins_name>]

You can read a property (for example the CLK_FREQ) using the command below:

get_property CLK_FREQ [get_pins <pin_name>]

In the IP that was created in Step 1, the Interrupt was enabled. 

You can use the built-in utils in HSI to see if a pin is connected. 

This can be used to see if the interrupt pin is connected. 

This is shown in the commands below:

set int_pin [get_pins -of_objects [get_cells myip_0] -filter TYPE==INTERRUPT]
set intc_type [:hsi::utils::get_connected_intr_controller myip_0 $int_pin]

With all of this in mind, you can update the driver files using the HSI commands.


For more information on the HSI command, see (UG1138)


Step 3: Update the driver TCL file

In the driver files created from the IP Packager in step 1, open the TCL file in the data folder. This TCL file is ran during the BSP generation in SDK.

Here, this file will be updated to add the clock frequencies of the custom IP clock pins, and if the interrupt is connected using the commands discussed in step 2.

The updated TCL can be seen below:


proc generate {drv_handle} {
 xdefine_include_file $drv_handle "xparameters.h" "myip" "NUM_INSTANCES" "DEVICE_ID"  "C_S00_AXI_BASEADDR" "C_S00_AXI_HIGHADDR"
 custom $drv_handle "xparameters.h"
proc custom {drv_handle file_name} {
    set periph_name [get_property IP_NAME [get_cells  $drv_handle]]
    set found [string first $periph_name $drv_handle]
    if {$found != -1} {
     set ip_name [string toupper [string range $drv_handle $found [string length $drv_handle]]]
    } else {
     set ip_name [string toupper $drv_handle]

    if {$file_name != "test"} {
    set file_handle [::hsi::utils::open_include_file $file_name]
    } else {
     set file_handle [open "test.txt" "w"]
    puts $file_handle "/* This is from the custom addition $ip_name */"
    set clk_pins [get_pins -of_objects [get_cells $drv_handle] -filter TYPE==clk]
    for {set i 0} {$i < [llength $clk_pins]} {incr i} {
     set clk_freq [get_property CLK_FREQ [lindex $clk_pins $i]]
     set clk_name [string toupper [get_property NAME [lindex $clk_pins $i]]]
     puts $file_handle "\#define XPAR_${ip_name}_${clk_name} $clk_freq" 
    set int_pin [get_pins -of_objects [get_cells $drv_handle] -filter TYPE==INTERRUPT]
    set intc_periph_type [::hsi::utils::get_connected_intr_cntrl myip_0 $int_pin]
    if {$intc_periph_type != ""} {
     puts $file_handle "\#define XPAR_${ip_name}_INTERRUPT_CONNECTED 1"
    } else {
     puts $file_handle "\#define XPAR_${ip_name}_INTERRUPT_CONNECTED 0"
    close $file_handle


Here, a custom proc was added. 

This proc is called by the main proc in the TCL (generate), which is called during BSP generation. 

The custom proc does the following:

  • Opens the xparameters.h, or a test.txt file (test.txt is from testing purposes)
  • Finds the IP name using the drv_handler. If the IP is in a sub block, only the driver name is used.
  • Gets all of the clock pins on the custom IP, and outputs these to the file
  • Sees if the interrupt is connected, outputs this to the file
  • Closes the file

To test, source this TCL and run the custom proc. 

To use the test file, pass the test parameter.

For example:

This will generate a test.txt file in the same directory as the TCL. 

This can be opened and verified. 

This should look like the following:

Step 4: Test the BSP

Once users are happy with the Tcl script, this can then be tested in SDK. 

Add the custom driver to the repository in SDK. Xilinx Tools -> Repositories

Rescan Repositories -> Apply -> OK

Generate the BSP, and view the generated xparameters.h file. 

This should contain the custom info:

Note: The driver used in this demo has been attached to this Answer Record.



タイトル サイズ ファイルタイプ
ip_repo.zip 30 KB ZIP
AR# 64980
日付 07/23/2015
ステータス アクティブ
種類 一般
  • Vivado Design Suite - 2015.3
  • Vivado Design Suite - 2015.2
  • Vivado Design Suite - 2015.1