Main Content

Generate Software Interface Script to Probe and Rapidly Prototype HDL IP Core

When you run the hardware-software co-design workflow for SoC platforms, you generate an HDL IP core for the DUT algorithm and then integrate the IP core into the reference design. See Hardware-Software Co-Design Workflow for SoC Platforms.

To rapidly prototype and test the HDL IP core on the target hardware, you can generate a software interface script. The script contains the DUT ports and interface mapping information, which HDL Coder™ uses to create the AXI drivers and access the HDL IP core.

Prerequisites

Generate Software Interface

When running the IP Core Generation workflow, you can generate a software interface script and model from the HDL Workflow Advisor UI or at the command line.

From the UI, in the Embedded System Integration > Generate Software Interface task, select the Generate Software interface script check box.

When you run the IP Core Generation workflow to the Generate Software Interface task and select the Generate MATLAB software interface script check box, two MATLAB files are generated:

  • gs_modelName_setup.m, which is a setup script that adds the AXI4 slave and AXI4-Stream interfaces. The script also contains DUT port objects that have the port name, direction, data type, and interface mapping information. The script then maps the DUT ports to the corresponding interfaces.

  • gs_modelName_interface.m, which creates a target object, instantiates the setup script gs_modelName_setup.m, and then connects to the target hardware. The script then sends read and write commands to the generated HDL IP core.

If you are targeting standalone FPGA boards, you cannot generate a software interface model. Instead, you can generate a software interface script and test the IP core by using the MATLAB AXI Master driver.

  1. In the Set Target Reference Design task, set Insert JTAG MATLAB as AXI Master to on. Run the workflow to the Generate Software Interface task.

  2. In the Generate Software Interface task, select the Generate Software interface script check box and run this task.

At the command line, export the HDL Workflow Advisor settings to a script, and then use these properties with the Workflow Configuration object. This script specifies running the software interface task by generating the model and script. If you skip the task by setting the RunTaskGenerateSoftwareInterface to false, then the model and script are not generated. See Configure and Run IP Core Generation Workflow with a Script.

% Export Workflow Configuration Script

% ...

%% Load the Model
load_system('hdlcoder_led_blinking');

%% Model HDL Parameters
% Set Model HDL parameters

% ...

hdlset_param('hdlcoder_led_blinking', 'SynthesisTool', 'Xilinx Vivado');
hdlset_param('hdlcoder_led_blinking', 'Workflow', 'IP Core Generation');

% ...

% Set Workflow tasks to run
hWC.RunTaskGenerateSoftwareInterface = true;
hWC.GenerateSoftwareInterfaceModel = true;
hWC.GenerateSoftwareInterfaceScript = true;

% ...

%% Run the workflow
hdlcoder.runWorkflow('hdlcoder_led_blinking/led_counter', hWC);

Software Interface Script

For rapid prototyping and testing the HDL IP core functionality, use the software interface script. The script is a MATLAB file that is generated based on the reference design and target platform interface table settings. It contains commands that enable you to connect to the target hardware, and write to or read from the generated IP core from MATLAB. For standalone FPGA boards, use the generated software interface script to verify the HDL IP core functionality by using the MATLAB AXI Master.

The software interface script has the same name as your original model with the prefix gs_ and the postfix _interface. The script instantiates a setup function that is generated when you enable the generation of the software interface script. For example, this code shows the setup function generated for the model hdlcoder_sfir_fixed_stream.slx, with the reference design and target platform interface table settings previously specified. The setup function contains commands for the AXI4 slave and AXI4-Stream interfaces that HDL Coder uses to control the DUT ports in the generated HDL IP core that are mapped to the corresponding interfaces.

function gs_hdlcoder_sfir_fixed_stream_setup(hFPGA)
%--------------------------------------------------------------------------
% Software Interface Script Setup
% 
% Generated with MATLAB 9.10 (R2021a) at 09:13:05 on 10/07/2020.
% This function was created for the IP Core generated from design 'hdlcoder_sfir_fixed_stream'.
% 
% Run this function on an "fpga" object to configure it with 
% the same interfaces as the generated IP core.
%--------------------------------------------------------------------------

%% AXI4-Lite
addAXI4SlaveInterface(hFPGA, ...
	"InterfaceID", "AXI4-Lite", ...
	"BaseAddress", 0xA0000000, ...
	"AddressRange", 0x10000);

hPort_h_in1 = hdlcoder.DUTPort("h_in1", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Lite", ...
	"IOInterfaceMapping", "0x100");

hPort_h_in2 = hdlcoder.DUTPort("h_in2", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Lite", ...
	"IOInterfaceMapping", "0x104");

hPort_h_in3 = hdlcoder.DUTPort("h_in3", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Lite", ...
	"IOInterfaceMapping", "0x108");

hPort_h_in4 = hdlcoder.DUTPort("h_in4", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Lite", ...
	"IOInterfaceMapping", "0x10C");

mapPort(hFPGA, [hPort_h_in1, hPort_h_in2, hPort_h_in3, hPort_h_in4]);

%% AXI4-Stream
addAXI4StreamInterface(hFPGA, ...
	"InterfaceID", "AXI4-Stream", ...
	"WriteEnable", true, ...
	"WriteFrameLength", 1024, ...
	"ReadEnable", true, ...
	"ReadFrameLength", 1024);

hPort_x_in_data = hdlcoder.DUTPort("x_in_data", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Stream");

hPort_y_out_data = hdlcoder.DUTPort("y_out_data", ...
	"Direction", "OUT", ...
	"DataType", numerictype(1,32,20), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4-Stream");

mapPort(hFPGA, [hPort_x_in_data, hPort_y_out_data]);

end

This is an example setup function for a model with a bus mapped to an AXI4 slave interface. As shown in the script, bus elements are represented as subports of hdlcoder.DUTPort objects.

function gs_AXI4SlaveMultipleBus_setup(hFPGA)
%--------------------------------------------------------------------------
% Software Interface Script Setup
% 
% Generated with MATLAB 9.10 (R2021a) at 16:20:32 on 16/11/2020.
% This function was created for the IP Core generated from design 'AXI4SlaveMultipleBus'.
% 
% Run this function on an "fpga" object to configure it with the same interfaces as the generated IP core.
%--------------------------------------------------------------------------

%% AXI4
addAXI4SlaveInterface(hFPGA, ...
	"InterfaceID", "AXI4", ...
	"BaseAddress", 0x400D0000, ...
	"AddressRange", 0x10000);

hPort_bus1_in_scalar_in1 = hdlcoder.DUTPort("scalar_in1", ...
	"Direction", "IN", ...
	"DataType", numerictype('single'), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4", ...
	"IOInterfaceMapping", "0x100");

hPort_bus1_in_scalar_in2 = hdlcoder.DUTPort("scalar_in2", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,8,0), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4", ...
	"IOInterfaceMapping", "0x104");

hPort_bus1_in_scalar_in3 = hdlcoder.DUTPort("scalar_in3", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,32,0), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4", ...
	"IOInterfaceMapping", "0x108");

hPort_bus1_in_scalar_in4 = hdlcoder.DUTPort("scalar_in4", ...
	"Direction", "IN", ...
	"DataType", numerictype(1,16,10), ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4", ...
	"IOInterfaceMapping", "0x10C");

hPort_bus1_in_vector_in = hdlcoder.DUTPort("vector_in", ...
	"Direction", "IN", ...
	"DataType", numerictype(0,32,0), ...
	"Dimension", [1 2], ...
	"IOInterface", "AXI4", ...
	"IOInterfaceMapping", "0x110");

hPort_bus1_in = hdlcoder.DUTPort("bus1_in", ...
	"Direction", "IN", ...
	"DataType", "Bus", ...
	"Dimension", [1 1], ...
	"IOInterface", "AXI4", ...
	"SubPorts", [hPort_bus1_in_scalar_in1, hPort_bus1_in_scalar_in2, hPort_bus1_in_scalar_in3, hPort_bus1_in_scalar_in4, hPort_bus1_in_vector_in]);

The software interface script instantiates this setup function to connect to the target and send read or write commands. You can uncomment and send meaningful data by using the inputs to the DUT in your original model. After interfacing with the hardware, the script disconnects from the hardware resource associated with the fpga object.

%--------------------------------------------------------------------------
% Software Interface Script
% 
% Generated with MATLAB 9.10 (R2020b) at 09:13:10 on 10/07/2020.
% This script was created for the IP Core generated from design 'hdlcoder_sfir_fixed_stream'.
% 
% Use this script to access DUT ports in the design mapped to compatible IP core interfaces.
% You can write to input ports in the design and read from output ports directly from MATLAB.
%
% To write to input ports, use the "writePort" command and specify port name and input data. 
% The input data will be cast to the DUT port's data type before writing. 
%
% To read from output ports, use the "readPort" command and specify the port name. 
% The output data will be returned with the same data type as the DUT port.
%
% Use the "release" command to release MATLAB's control of the hardware resources.
%--------------------------------------------------------------------------

%% Create fpga object
hFPGA = fpga("Xilinx");

%% Setup fpga object
% This function configures "fpga" object with same interfaces as the generated IP core
gs_hdlcoder_sfir_fixed_stream_setup(hFPGA);

%% Write/read DUT ports
% Uncomment the following lines to write/read DUT ports in the generated IP Core.
% Update the example data in the write commands with meaningful data to write to the DUT.
%% AXI4-Lite
writePort(hFPGA, "h_in1", zeros([1 1]));
writePort(hFPGA, "h_in2", zeros([1 1]));
writePort(hFPGA, "h_in3", zeros([1 1]));
writePort(hFPGA, "h_in4", zeros([1 1]));

%% AXI4-Stream
writePort(hFPGA, "x_in_data", zeros([1 1024]));
data_y_out_data = readPort(hFPGA, "y_out_data");

%% Release hardware resources
release(hFPGA)

See Prototype FPGA Design on Hardware with Live Data by Using MATLAB Commands

This is an example software interface script to read and write data for models that have bus data types mapped to AXI4 slave interfaces.

To write to a bus port, you can either:

  • Write to individual subports by specifying the full subport name, such as bus1_in.scalar_in1.

  • Write to the entire bus by specifying the top port name, such as bus1_in. Pass the data to be written as a struct whose filed names match the subport names. Not all subport names need to be part of the struct. The subports without corresponding struct fields are skipped when writing to the port.

To read from a bus port, you can either:

  • Read an individual subport by specifying the full subport name such as bus1_out.scalar.in1.

  • Read the entire bus port by specifying the top port name such as bus1_out.

%--------------------------------------------------------------------------
% Software Interface Script
% 
% Generated with MATLAB 9.10 (R2021a) at 16:20:33 on 16/11/2020.
% This script was created for the IP Core generated from design 'AXI4SlaveMultipleBus'.
% 
% Use this script to access DUT ports in the design that were mapped to compatible IP core interfaces.
% You can write to input ports in the design and read from output ports directly from MATLAB.
% To write to input ports, use the "writePort" command and specify the port name and input data. The input data will be cast to the DUT port's data type before writing.
% To read from output ports, use the "readPort" command and specify the port name. The output data will be returned with the same data type as the DUT port.
% Use the "release" command to release MATLAB's control of the hardware resources.
%--------------------------------------------------------------------------

%% Create fpga object
hFPGA = fpga("Xilinx");

%% Setup fpga object
% This function configures the "fpga" object with the same interfaces as the generated IP core
gs_AXI4SlaveMultipleBus_setup(hFPGA);

%% Write/read DUT ports
% Uncomment the following lines to write/read DUT ports in the generated IP Core.
% Update the example data in the write commands with meaningful data to write to the DUT.
%% AXI4

% There are two ways to write a DUT bus ports
% (1). Prepare a struct value and write it to the whole bus port.
writePort(hFPGA, "bus1_in", struct());
% (2). Prepare a value for each member of the bus and write it individually.
writePort(hFPGA, "bus1_in.scalar_in1", zeros([1 1]));
writePort(hFPGA, "bus1_in.scalar_in2", zeros([1 1]));
writePort(hFPGA, "bus1_in.scalar_in3", zeros([1 1]));
writePort(hFPGA, "bus1_in.scalar_in4", zeros([1 1]));
writePort(hFPGA, "bus1_in.vector_in", zeros([1 2]));

See Also

Objects

Functions

Related Topics