This example shows how to use the HDL Coder™ IP Core Generation Workflow to develop reference designs for Xilinx® parts without an embedded ARM® processor present, but which still utilize the HDL Coder™ generated AXI interface to control the DUT. This example will use the Xilinx Kintex-7 KC705 board and a JTAG to AXI Master IP in the reference design to access the HDL Coder™ generated DUT registers.
Xilinx Vivado™ 2015.4
Xilinx Kintex-7 KC705 development board
HDL Coder™ support package for Xilinx FPGA Boards
There are many designs which will benefit from using the HDL Coder™ IP Core Generation Workflow without using either an embedded ARM® processor or an Embedded Coder™ Support Package, but which still leverages the HDL Coder generated AXI4-Lite registers. These designs include:
MicroBlaze™ + HDL Coder™ IP Core
PCIe Endpoint + HDL Coder™ IP Core
JTAG Master + HDL Coder™ IP Core
For this example, you will use a JTAG Master to access the HDL Coder™ generated registers. The JTAG Master design can be used on its own to tune values on a system, or it can be used as a starting point for other designs which treat the HDL Coder™ IP Core as a memory mapped peripheral.
The following is a system level diagram for this JTAG Master system:
The reference design, "Xilinx JTAG to AXI Master", uses Vivado™ IP for the JTAG to AXI Master and therefore requires using the Vivado™ Tcl console to issue reads and writes:
The plugin_rd.m for this reference design is shown below:
function hRD = plugin_rd() % Reference design definition
% Copyright 2014-2016 The MathWorks, Inc.
% Construct reference design object hRD = hdlcoder.ReferenceDesign('SynthesisTool', 'Xilinx Vivado');
hRD.ReferenceDesignName = 'Xilinx JTAG to AXI Master'; hRD.BoardName = 'Xilinx Kintex-7 KC705 development board';
% Tool information hRD.SupportedToolVersion = {'2015.4'};
%% Add custom design files % add custom Vivado design hRD.addCustomVivadoDesign( ... 'CustomBlockDesignTcl', 'system_top.tcl',... 'VivadoBoardPart', 'xilinx.com:kc705:part0:1.1');
% add custom files, use relative path
hRD.CustomFiles = {};
% custom constraint files
hRD.CustomConstraints = {};
%% Add interfaces % add clock interface hRD.addClockInterface( ... 'ClockConnection', 'system_0/clk_out1', ... 'ResetConnection', 'system_0/peripheral_aresetn',... 'DefaultFrequencyMHz', 125,... 'MinFrequencyMHz', 10,... 'MaxFrequencyMHz', 250,... 'ClockNumber', 1,... 'ClockModuleInstance', 'system_0/clk_wiz_0');
% add AXI4 and AXI4-Lite slave interfaces hRD.addAXI4SlaveInterface( ... 'InterfaceConnection', 'system_0/M_AXI', ... 'BaseAddress', '0x44A00000',... 'MasterAddressSpace', 'system_0/jtag_axi_0/Data',... 'MasterAddressSpace', 'system_0/hdlverifier_jtag_master_0/axi4m',... 'InterfaceType', 'AXI4-Lite',... % [ 'AXI4-Lite'| 'AXI4' ] 'InterfaceID', 'JTAG AXI Interface'); % string name in interface table
% Specify Embedded Coder Support Package to use for Software Interface hRD.EmbeddedCoderSupportPackage = hdlcoder.EmbeddedCoderSupportPackage.None; % [ None | Zynq | AlteraSoC ]
Using the above reference design you will generate an HDL IP Core that blinks LEDs on the KC705 board. You will then use the Vivado Tcl interfaces to read and write the DUT registers. The files used in the following demonstration are located at:
matlab/toolbox/hdlcoder/hdlcoderdemos/customboards/KC705
1. Add the JTAG to AXI Master reference design files to the MATLAB path using the command:
>> addpath(fullfile(matlabroot,'toolbox','hdlcoder','hdlcoderdemos','customboards','KC705'));
2. Set up the Xilinx Vivado™ tool path by using the following command:
>> hdlsetuptoolpath('ToolName', 'Xilinx Vivado', 'ToolPath', 'C:\Xilinx\Vivado\2015.4\bin\vivado.bat');
Use your own Xilinx Vivado™ installation path when executing the command.
3. Open the Simulink model that implements LED blinking using the command:
open_system('hdlcoder_led_blinking')
4. Launch HDL Workflow Advisor from the hdlcoder_led_blinking/led_counter
subsystem by right-clicking the led_counter
subsystem, and selecting HDL Code > HDL Workflow Advisor.
5. Select reference design from the drop down in step 1.2
6. Assign register ports to the "JTAG AXI Interface". These will then be accessible at the hex offset shown in the table.
7. Run the remaining steps in the workflow to generate a bitstream and program the target device.
Notice that unlike the Zynq-based reference design, there is no 'Generate Software Interface Model' task. In the reference design "plugin_rd.m", you can disable this task using the following command:
% Disable 'Generate Software Interface Model' task hRD.EmbeddedCoderSupportPackage = hdlcoder.EmbeddedCoderSupportPackage.None; %None
The Base Address for an HDL Coder™ IP Core is defined in the reference design plugin_rd.m with the following command:
% add AXI4 and AXI4-Lite slave interfaces hRD.addAXI4SlaveInterface( ... 'InterfaceConnection', 'system_0/M_AXI', ... 'BaseAddress', '0x44A00000',... 'MasterAddressSpace', 'system_0/hdlverifier_jtag_master_0/axi4m',... 'InterfaceType', 'AXI4-Lite',... 'InterfaceID', 'JTAG AXI Interface');
For this design, the base address is 0x44A0_0000
. The offsets can be found in the IP Core Report Register Address Mapping table:
Before you open a Vivado™ console, lets look at the basic commands to issue reads and writes. The Vivado™ AXI interface is a two step process. First, you need to create an AXI transaction (or a series of AXI transaction), then you execute them on the specified AXI Master:
create_hw_axi_txn
run_hw_axi
For example, assume you would like to write the 32 bit hex value '0x12345678' to the IP Core register defined by offset '0x100', you would first create the transaction:
Vivado% create_hw_axi_txn axi_write_0x100 [get_hw_axis hw_axi_1] -address 44a0_0100 -data 1234_5678 -type write
For more information on these commands you can view help at any time via the following Tcl commands:
Vivado% create_hw_axi_txn -help Vivado% run_hw_axi -help
or see the Vivado documentation pg174-jtag-axi for more details.
The Vivado™ Tcl console can be accessed at the bottom of the Vivado™ GUI or launched directly in a stand alone mode. This example will use the stand alone Tcl console.
The following commands can be used to open the JTAG device and setup an 'enable' and 'disable' write to the DUT. These can be entered directly into the Vivado Tcl console or saved in a Tcl file and sourced. For simplicity, copy the following Tcl commands into a file "open_jtag.tcl":
# Open connection to the JTAG Master open_hw connect_hw_server open_hw_target refresh_hw_device [lindex [get_hw_devices] 0]
# Create some reads/writes create_hw_axi_txn wr_enable [get_hw_axis hw_axi_1] -address 44a0_0004 -data 0000_0001 -type write create_hw_axi_txn wr_disable [get_hw_axis hw_axi_1] -address 44a0_0004 -data 0000_0000 -type write
Now launch the Vivado™ Tcl console, sourcing the file you just created:
>> system('vivado -mode tcl -source open_jtag.tcl&')
When you are done using the JTAG Master, close the connection using the following Tcl commands:
# Close and disconnect from the JTAG Master close_hw_target; disconnect_hw_server;
Using a JTAG to AXI Master is a simple way to interface with HDL Coder™ IP core registers in systems which do not have an embedded ARM® processor, such as the Kintex-7. This can be used as first step to debug stand alone HDL Coder™ IP cores, used prior to hand coding software for soft processors, such as MicroBlaze™, or as an easy way to tune parameters on a running system.