This blog provides an example on how a Python script can be used in debugging Xilinx PCIe designs. The script attached to this blog has been created with contribution from the community.
If you have already been using a similar approach to the one that is explained here or if you decide to use the provided script and enhance it further, we would be delighted if you could share your script with us and we will share it with the PCIe community members in this forum.
The provided technique can be applied to all designs and is not specific to PCIe only.
Getting the CSV:
Using a Python script to do debug analysis is made possible and more importantly made easier by the ILA file produced by Vivado ILA. This can be converted into a CSV file by renaming the *.ila extension to *.zip and then unzipping the resulting file.
The unzipped folder will contain the following list of files.
Python provides libraries for CSV file analysis which can be used to do thorough analysis of the debug signal data produced by Vivado ILA. The debug signals can also be viewed as a waveform in Vivado Hardware Manager. For analysis such as counting the number of packets in certain interfaces, interpreting the field values inside the packets etc., the python script approach would be much easier for custom debug.
Example Python Script Use Case
The provided Python script does the analysis on the ILA data containing RQ/RC/CQ/CC interface signals shown in the diagram below. This block diagram is from (PG213) for the UltraScale+ Devices Integrated Block for PCI Express IP.
The script identifies the valid packets on each interface, extracts descriptor fields in each packet, and reports out values for each field.
Python Example Code for PCIe Debug:
Below are the steps that the script goes through:
Open the CSV file.
Extract data from the selected CSV file.
Extract specific columns / headers which contain the desired data.
Identify valid packets by using ‘tready’, ‘tvalid’ and ‘tlast’ as qualifiers.
Extract valid tdata value and using a function, do hexadecimal to binary conversion.
The binary conversion is required to extract bit level data from ‘tdata’.
Print descriptor fields with hexadecimal data.
The func_rq_pkt_analysis() function below takes in the CSV file and decides which interface to run analysis on based on the tready value provided.
The code below identifies the column number in the .csv file for the respective fields as shown:
Extract only the tready, tdata, tvalid and tlast values and store them in the dictionary as values for the corresponding index, which will be used as the dictionary key.
The next step is to do the analysis of the data stored in the dictionary. The dictionary contains tdata, tready, tvalid and tlast.
The for loop goes through each row in the dictionary and if it finds both tready and tvalid as ‘1’, it copies the corresponding data into a variable. The tdata is stored as a hexadecimal number in the CSV file. To do bit level extraction for descriptor field identification, the hexadecimal value is converted into binary.
The extraction of the descriptor field is done based on the descriptor format provided in (PG213). The example below shows the descriptor for the Completion Completer (CC) interface.
To print the descriptor field values, the binary value is again converted into hexadecimal by using the bin_to_hex_print( ) function.
This function is defined as follows:
Below is an example output for the waveform.csv file attached to this blog.
Example Code Limitations
The example code is provided just as a proof of concept. The provided script can be used ‘as is’ in the following scenarios:
1. Packet consists of one data beat i.e. tready/tvalid and tlast are all asserted in the same clock cycle. 2. Straddling is not used. 3. The signal naming for tdata, tready, tvalid and tlast for the corresponding interfaces is the same as in the .csv file attached to this blog.
PCIe Debug use cases using Python
The example Python script can be extended to debug various scenarios as listed below:
Count the number of packets on each interface.
Do analysis of packets on the user interface with straddling enabled.
Support for analysis of multi data beats packets e.g. packets spanning to multiple clock cycles.
Verify the receipt of split completion packets.
Given sufficient buffer size of the ILA capture window, verify that correct completion is generated on the CC interface by the user logic and that similarly a completion is received on the RC interface for the corresponding request on the RQ interface.