Vivado Mismatch using volatile
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
volatile unsigned int g = 0; int a[256] = {0}; int c = 0; void d(char b) { c = (c & 4095) ^ a[(c ^ b) & 15]; } void e(long f) { d(f); d(f >> 8); d(f >> 16); d(f >> 24); d(f >> 32); d(f >> 40); d(f >> 48); } int result() { for (int i = 0; i < 56; i++) a[i] = i; e(g); e(-2L); return c; }
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 = F
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:32:50 2020... INFO: [COSIM 212-316] Starting C post checking ... 1c1 < checksum = 0 --- > checksum = F Verilog result is 0 C output:checksum = F 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: 43.31 seconds; peak allocated memory: 92.524 MB. INFO: [Common 17-206] Exiting vivado_hls at Fri Oct 2 16:32:51 2020...