Vivado Shift Bug
| Reported | Fixed |
|---|---|
| Issue | X |
The following bug produces an error in Vivado HLS 2018.3, 2019.1 and 2019.2.
To create the project layout, we can first create the ./bug.c file which produces the bug.
./bug.c
unsigned int b = 0x1194D7FF; int a[6] = {1, 1, 1, 1, 1, 1}; int result() { for (int c = 0; c < 2; c++) b = b >> a[c]; return b; }
The program repeatedly shifts a large integer value b right by the values stored in array a. Vivado HLS returns 0x006535FF, but the result returned by GCC (and subsequently confirmed manually to be the correct one) is 0x046535FF.
We then have to generate a main function to provide the golden output. We first write the following driver into ./bug_driver.c which contains the main function that generates the checksum.
./bug_driver.c
#include "stdio.h" int result(); int main() { printf("checksum = %X\n", result()); }
Then generate the golden output using GCC by compiling the driver with the initial bug and check the golden output. This golden output is then written to out.gold.txt.
gcc bug_driver.c bug.c -o bug_gcc ./bug_gcc | tee out.gold.txt
checksum = 46535FF
We then also need to provide a test bench for Vivado that will detect a mismatch between the Verilog simulation and C output. This loads the file out.gold.txt and checks that the output is equivalent to the current result.
./bug_tb.c
#include <stdio.h> unsigned int result(); int main () { FILE *fp; FILE *fp1; unsigned int resultOut; char str[1000]; fp=fopen("out.txt","w"); fp1=fopen("out.gold.txt", "r"); resultOut = result(); printf("Verilog result is %X\n", resultOut); printf("C output:"); while (fgets(str, 1000, fp1) != NULL) printf("%s", str); fprintf(fp,"checksum = %X\n",resultOut); fclose(fp); fclose(fp1); printf ("Comparing against output data \n"); if (system("diff -w out.txt out.gold.txt")) { fprintf(stdout, "*******************************************\n"); fprintf(stdout, "FAIL: Output DOES NOT match the golden output\n"); fprintf(stdout, "*******************************************\n"); return 1; } else { fprintf(stdout, "*******************************************\n"); fprintf(stdout, "PASS: The output matches the golden output!\n"); fprintf(stdout, "*******************************************\n"); return 0; } }
Finally, we create the tcl file to create the Vivado project and include all the relevant source files.
./vivado.tcl
open_project -reset bug set_top result add_files bug.c add_files -tb out.gold.txt add_files -tb bug_tb.c open_solution -reset "solution1" set_part {xc7z020-clg484-1} create_clock -period 10 -name default csynth_design csim_design cosim_design export_design -format ip_catalog exit
Then we can run the vivado_hls command to run Vivado HLS and check for the bug.
vivado_hls -f vivado.tcl | tail -n24
INFO: [Common 17-206] Exiting xsim at Fri Oct 2 16:10:49 2020... INFO: [COSIM 212-316] Starting C post checking ... 1c1 < checksum = 6535FF --- > checksum = 46535FF Verilog result is 6535FF C output:checksum = 46535FF Comparing against output data ******************************************* FAIL: Output DOES NOT match the golden output ******************************************* ERROR: [COSIM 212-361] C TB post check failed, nonzero return value '1'. ERROR: [COSIM 212-4] *** C/RTL co-simulation finished: FAIL *** INFO: [COSIM 212-211] II is measurable only when transaction number is greater than 1 in RTL simulation. Otherwise, they will be marked as all NA. If user wants to calculate them, please make sure there are at least 2 transactions in RTL simulation. command 'ap_source' returned error code while executing "source vivado.tcl" ("uplevel" body line 1) invoked from within "uplevel \#0 [list source $arg] " INFO: [HLS 200-112] Total elapsed time: 42.76 seconds; peak allocated memory: 80.380 MB. INFO: [Common 17-206] Exiting vivado_hls at Fri Oct 2 16:10:49 2020...