Last active
March 5, 2022 14:12
-
-
Save Aniruddha-Deb/192462b220dba7e9c4316d6fdbfdee74 to your computer and use it in GitHub Desktop.
generate VHDL test benches from an assembly file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
typedef char byte; | |
typedef unsigned int word; | |
char* header = | |
"-- TESTCASE AUTOGENERATED by gentest\n" | |
"library ieee;\n" | |
"use ieee.std_logic_1164.all;\n" | |
"use ieee.numeric_std.all;\n" | |
"use work.MyTypes.all;\n" | |
"\n" | |
"entity cpu_tb is\n" | |
"end cpu_tb;\n" | |
"\n" | |
"architecture cpu_tb_arc of cpu_tb is\n" | |
" signal clock: std_logic := '0';\n" | |
" constant clock_period: time := 2 ns;\n" | |
" signal memory: mem(127 downto 0) := (\n"; | |
char* footer = "begin\n" | |
" uut: entity work.cpu generic map (memory) port map (clock);\n" | |
"\n" | |
" clock <= not clock after clock_period/2;\n" | |
"\n" | |
"end cpu_tb_arc;\n"; | |
byte* get_file_as_bytes(char* fname) { | |
FILE *fileptr; | |
char *buffer; | |
long filelen; | |
fileptr = fopen(fname, "rb"); // Open the file in binary mode | |
fseek(fileptr, 0, SEEK_END); // Jump to the end of the file | |
filelen = ftell(fileptr); // Get the current byte offset in the file | |
rewind(fileptr); // Jump back to the beginning of the file | |
buffer = (char *)malloc(filelen * sizeof(char)); // Enough memory for the file | |
fread(buffer, filelen, 1, fileptr); // Read in the entire file | |
fclose(fileptr); // Close the file | |
return buffer; | |
} | |
int main(int argc, char** argv) { | |
// first argument contains assembly file to generate testcase for | |
// second argument is output vhdl filename | |
if (argc < 3) { | |
printf("Incorrect format. Ending."); | |
return 1; | |
} | |
char* fname = argv[1]; | |
// compile the file | |
char* cmd = (char*)malloc(200); | |
sprintf(cmd, "/Applications/ARM/bin/arm-none-eabi-as -march=armv4t -mbig-endian %s", fname); | |
int result = system(cmd); | |
if (result != 0) { | |
printf("Could not compile file. Exiting."); | |
return 1; | |
} | |
free(cmd); | |
// post compilation, open the executable as a byte array | |
byte* fbytes = get_file_as_bytes("a.out"); | |
// open output file for writing | |
FILE *outfile; | |
outfile = fopen(argv[2], "w"); | |
fprintf(outfile, header); | |
// compiled as an ELF on my machine; commands start from 13th word, in | |
// big endian order (big endian makes a hexdump easier to read) | |
for (int i = 13*4,j=0; ; i+=4,j++) { | |
word cmd = ((word)fbytes[i] << 24) | | |
((word)fbytes[i+1] << 16) | | |
((word)fbytes[i+2] << 8) | | |
((word)fbytes[i+3]); | |
if (cmd == (((word)0x41)<<24)) { // ELF command signifying end of instructions | |
break; | |
} | |
else { | |
fprintf(outfile, " %d => X\"%02hhX%02hhX%02hhX%02hhX\",\n", j, fbytes[i], fbytes[i+1], fbytes[i+2], fbytes[i+3]); | |
} | |
} | |
fprintf(outfile, " others => X\"00000000\" );\n"); | |
fprintf(outfile, footer); | |
free(fbytes); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment