Commit 2f7b2e81 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra Committed by Tomasz Wlostowski

Added a tool which generates a VHDL initialization file.

parent b22dde76
......@@ -6,5 +6,7 @@
tools/zpu-loader
tools/vuart_console
tools/genraminit
tools/genramvhd
tools/lm32-loader
wrc_disasm.S
wrc.ram
......@@ -59,6 +59,7 @@ all: $(OBJS)
${OBJCOPY} -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -d $(OUTPUT).elf > $(OUTPUT)_disasm.S
./tools/genraminit $(OUTPUT).bin 0 > $(OUTPUT).ram
./tools/genramvhd $(OUTPUT).bin > $(OUTPUT).vhd
clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram
......
......@@ -10,7 +10,7 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
all: lm32-loader genraminit vuart_console
all: lm32-loader genraminit genramvhd vuart_console
OBJS_LOADER = lm32-loader.o rr_io.o mini_bone/ptpd_netif.o mini_bone/minibone_lib.o
......@@ -21,6 +21,9 @@ lm32-loader: $(OBJS_LOADER)
genraminit: genraminit.o
${CC} -o genraminit genraminit.o
genramvhd: genramvhd.o
${CC} -o genramvhd genramvhd.o
vuart_console: vuart_console.o rr_io.o
${CC} -o vuart_console vuart_console.o rr_io.o
......
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <unistd.h> /* getopt */
const char* program;
const char* package;
const char* filename;
long width;
int bigendian;
int verbose;
void help() {
fprintf(stderr, "Usage: %s [OPTION] <filename>\n", program);
fprintf(stderr, "\n");
fprintf(stderr, " -w <width> width of values in bytes [1/2/4/8/16] (4)\n");
fprintf(stderr, " -p <package> name of the output package (filename)\n");
fprintf(stderr, " -b big-endian operation (*)\n");
fprintf(stderr, " -l little-endian operation \n");
fprintf(stderr, " -v verbose operation\n");
fprintf(stderr, " -h display this help and exit\n");
fprintf(stderr, "\n");
fprintf(stderr, "Report Etherbone bugs to <white-rabbit-dev@ohwr.org>\n");
}
/* We don't want localized versions from ctype.h */
inline int my_isalpha(char c) {
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z');
}
inline int my_isok(char c) {
return c == '_' || my_isalpha(c) ||
(c >= '0' && c <= '9');
}
int main(int argc, char **argv) {
int j, opt, error, i_width;
long i, elements, columns, entry_width;
char* value_end;
unsigned char x[16]; /* Up to 128 bit */
char buf[100];
FILE* f;
/* Default values */
program = argv[0];
package = 0; /* auto-detect */
width = 4;
bigendian = 1;
verbose = 0;
/* Process the command-line */
while ((opt = getopt(argc, argv, "w:p:blvh")) != -1) {
switch (opt) {
case 'w':
width = strtol(optarg, &value_end, 0);
if (*value_end || /* bad integer */
((width-1)&width) != 0 || /* not a power of 2 */
width == 0 ||
width > 16) {
fprintf(stderr, "%s: invalid value width -- '%s'\n", program, optarg);
error = 1;
}
break;
case 'p':
package = optarg;
break;
case 'b':
bigendian = 1;
break;
case 'l':
bigendian = 0;
break;
case 'v':
verbose = 1;
break;
case 'h':
help();
return 1;
case ':':
case '?':
error = 1;
break;
default:
fprintf(stderr, "%s: bad getopt result\n", program);
return 1;
}
}
if (optind + 1 != argc) {
fprintf(stderr, "%s: expecting one non-optional argument: <filename>\n", program);
return 1;
}
filename = argv[optind];
/* Confirm the filename exists */
if ((f = fopen(filename, "r")) == 0) {
fprintf(stderr, "%s: %s while opening '%s'\n", program, strerror(errno), filename);
return 1;
}
/* Deduce if it's aligned */
fseek(f, 0, SEEK_END);
elements = ftell(f);
rewind(f);
if (elements % width != 0) {
fprintf(stderr, "%s: initialization file '%s' is not a multiple of %ld bytes\n", program, filename, width);
return 1;
}
elements /= width;
/* Find a suitable package name */
if (package == 0) {
if (strlen(filename) >= sizeof(buf)-5) {
fprintf(stderr, "%s: filename too long to deduce package name -- '%s'\n", program, filename);
return 1;
}
/* Find the first alpha character */
while (*filename && !my_isalpha(*filename)) ++filename;
/* Start copying the filename to the package */
for (i = 0; filename[i]; ++i) {
if (my_isok(filename[i]))
buf[i] = filename[i];
else
buf[i] = '_';
}
buf[i] = 0;
strcat(buf, "_pkg");
if (i == 0) {
fprintf(stderr, "%s: no appropriate characters in filename to use for package name -- '%s'\n", program, filename);
return 1;
}
package = &buf[0];
} else {
/* Check for valid VHDL identifier */
if (!my_isalpha(package[0])) {
fprintf(stderr, "%s: invalid package name -- '%s'\n", program, package);
return 1;
}
for (i = 1; package[i]; ++i) {
if (!my_isok(package[i])) {
fprintf(stderr, "%s: invalid package name -- '%s'\n", program, package);
return 1;
}
}
}
/* Find how many digits it takes to fit 'elements' */
i_width = 1;
for (i = 10; i <= elements; i *= 10)
++i_width;
/* How wide is an entry of the table? */
entry_width = i_width + 6 + width*2 + 3;
columns = 76 / entry_width;
printf("-- AUTOGENERATED FILE (from genramvhd.c run on %s) --\n", argv[1]);
printf("library IEEE;\n");
printf("use IEEE.std_logic_1164.all;\n");
printf("use IEEE.numeric_std.all;\n");
printf("\n");
printf("library work;\n");
printf("use work.memory_loader_pkg.all;\n");
printf("\n");
printf("package %s is\n", package);
printf(" constant file_contents : t_meminit_array(%ld downto 0, %ld downto 0) := (\n", elements-1, (width*4)-1);
for (i = 1; i <= elements; ++i) {
if (i % columns == 1) printf(" ");
if (fread(x, 1, width, f) != width) {
perror("fread");
return 1;
}
printf("%*ld => x\"", i_width, i);
if (bigendian) {
for (j = 0; j < width; ++j)
printf("%02x", x[j]);
} else {
for (j = width-1; j >= 0; --j)
printf("%02x", x[j]);
}
printf("\"");
if (i == elements) printf(");\n");
else if (i % columns == 0) printf(",\n");
else printf(", ");
}
fclose(f);
printf("end %s;\n", package);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment