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...