Skeleton used for automatically generating main with multiple function calls to test correctness of hardware.
1. foo1.c
A function to test (example-returns absolute difference of the sum of the first two integers and third)
int foo1(int a, int b, int c){ int temp; temp = a + b; if (temp > c) return (temp - c); else return (c - temp); }
2. test.data
Function signature. Only the function name and number of arguments are used as of now.
Update: now recognizes signed and unsigned.
Format:
<funcName> <type1> <type2>...
foo1 unsigned signed unsigned
3. genInput.pl
Script to generates random sets of input, and create a c program with the function and main.
To run:
perl genInput.pl test.data <# of tests>
Code:
#test.data in the form: FuncName Type1 Type2..... #Type => input data type #Number of Test Sets $Nvectors = $ARGV[1]; print "#include <stdio.h>\n\n"; print "int main(void) {\n"; print "int ret;\n"; open (FILE, "$ARGV[0]"); while (<FILE>) { chop; # remove newline @tokens = split(/ +/); $funcName = $tokens[0]; # print "//CHECK: $#tokens\n"; for ($i = 0; $i < $Nvectors; $i++) { print "\nret = $funcName("; $count = 1; #Generate random integer for each input for ($j = 1; $j <= $#tokens; $j++) { $randInt = int(rand(100)); $vec[$count] = $randInt; #Stores generated input $count++; print "$randInt"; #',' if not the last argument, ')' if last if ($j < $#tokens) { print ", "; } else { print ");\n"; } } print "printf(\""; for ($j = 1; $j < $count; $j++) { $temp = $vec[$j]; print "$temp "; } print "%d\\n\", ret);\n"; } } close (FILE); print "\nreturn 0;\n}\n";
4. test.pl
Script to run genInput.pl, compile c program produced with output stored in output.data, generates a second c program with same input and compares output with correct output produced from first c program.
To run:
perl test.pl test.data <# of tests>
Code:
$Nvectors = $ARGV[1]; open (INPUT, "$ARGV[0]"); while (<INPUT>){ chop; @temp = split(/ +/); $funcName = $temp[0]; } close (INPUT); system ("rm gen_out.c a.out output.data test.c"); system ("cp foo1.c gen_out.c"); system ("perl genInput.pl test.data $Nvectors >> gen_out.c"); system ("gcc gen_out.c"); system ("./a.out > output.data"); system ("cp foo1.c test.c"); open (DATA, 'output.data'); open (TEST, '>>test.c'); print TEST "#include <stdio.h>\n\n"; print TEST "int main(void) {\n"; print TEST " int output[$Nvectors];\n"; @correct_output; $count = 0; while (<DATA>){ chomp; @tokens = split (/ +/); $out_index = $#tokens; $correct_output[$count] = $tokens[$out_index]; print TEST " output[$count] = $funcName("; for ($i = 0; $i < $out_index; $i++){ print TEST ("$tokens[$i]"); if ($i < ($out_index-1)) { print TEST ", "; } else { print TEST ");\n" } } $count++; } close (DATA); print TEST "\n int correct_output[$Nvectors] = {"; for ($j = 0; $j <= $#correct_output; $j++){ print TEST ("$correct_output[$j]"); if ($j < $#correct_output){ print TEST (", "); } } print TEST ("};\n\n"); print TEST (" int i;\n"); print TEST (" int count = 0;\n"); print TEST (" for (i=0; i < $Nvectors; i++){\n"); print TEST (" if (output[i] == correct_output[i]){\n"); print TEST (" count++;\n"); print TEST (" }\n"); print TEST (" }\n"); print TEST (" printf(\"\%d\\n\", count);\n"); print TEST (" return count;\n"); print TEST ("}\n"); close (TEST);
5. gen_out.c
Output from genInput.pl
int foo1(int a, int b, int c){ int temp; temp = a + b; if (temp > c) return (temp - c); else return (c - temp); } #include <stdio.h> int main(void) { int ret; ret = foo1(11, 56, 40); printf("11 56 40 %d\n", ret); ret = foo1(44, 95, 66); printf("44 95 66 %d\n", ret); ret = foo1(90, 34, 23); printf("90 34 23 %d\n", ret); ret = foo1(7, 22, 17); printf("7 22 17 %d\n", ret); ret = foo1(61, 28, 18); printf("61 28 18 %d\n", ret); ret = foo1(79, 64, 66); printf("79 64 66 %d\n", ret); ret = foo1(20, 57, 40); printf("20 57 40 %d\n", ret); ret = foo1(83, 83, 34); printf("83 83 34 %d\n", ret); ret = foo1(93, 70, 49); printf("93 70 49 %d\n", ret); ret = foo1(94, 22, 24); printf("94 22 24 %d\n", ret); return 0; }
6. output.data
Output (also contains input used) from gen_out
Format:
<input1> <input2>.....<output>
11 56 40 27 44 95 66 73 90 34 23 101 7 22 17 12 61 28 18 71 79 64 66 77 20 57 40 37 83 83 34 132 93 70 49 114 94 22 24 92
7. test.c
Final c program that test hardware functionality correctness.
int foo1(int a, int b, int c){ int temp; temp = a + b; if (temp > c) return (temp - c); else return (c - temp); } #include <stdio.h> int main(void) { int output[10]; output[0] = foo1(11, 56, 40); output[1] = foo1(44, 95, 66); output[2] = foo1(90, 34, 23); output[3] = foo1(7, 22, 17); output[4] = foo1(61, 28, 18); output[5] = foo1(79, 64, 66); output[6] = foo1(20, 57, 40); output[7] = foo1(83, 83, 34); output[8] = foo1(93, 70, 49); output[9] = foo1(94, 22, 24); int correct_output[10] = {27, 73, 101, 12, 71, 77, 37, 132, 114, 92}; int i; int count = 0; for (i=0; i < 10; i++){ if (output[i] == correct_output[i]){ count++; } } printf("%d\n", count); return count; }