T: improve to_vcd tracer
Make it compatible with 'template' gtwave files as found in openair's repository. The type VCD_NAME was added to the VCD IDs in T_messages.txt. The database processing code was adapted to use it. The tracer to_vcd was adapted to use it and render the produced vcd output compatible with the 'template' gtkwave files. When running to_vcd, do not forget to pass -vcd to use this feature.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ typedef struct {
|
||||
char **arg_type;
|
||||
char **arg_name;
|
||||
int asize;
|
||||
char *vcd_name;
|
||||
int id;
|
||||
} id;
|
||||
|
||||
@@ -138,6 +139,7 @@ id *add_id(database *r, char *idname, int i)
|
||||
r->i[r->isize].arg_type = NULL;
|
||||
r->i[r->isize].arg_name = NULL;
|
||||
r->i[r->isize].asize = 0;
|
||||
r->i[r->isize].vcd_name = NULL;
|
||||
r->i[r->isize].id = i;
|
||||
r->isize++;
|
||||
qsort(r->i, r->isize, sizeof(id), id_cmp);
|
||||
@@ -224,6 +226,12 @@ void add_desc(id *i, char *desc)
|
||||
i->desc = strdup(desc); if (i->desc == NULL) abort();
|
||||
}
|
||||
|
||||
void add_vcd_name(id *i, char *vcd_name)
|
||||
{
|
||||
if (i == NULL) {printf("ERROR: VCD_NAME line before ID line\n");exit(1);}
|
||||
i->vcd_name = strdup(vcd_name); if (i->vcd_name == NULL) abort();
|
||||
}
|
||||
|
||||
char *format_get_next_token(char **cur)
|
||||
{
|
||||
char *start;
|
||||
@@ -320,6 +328,7 @@ void *parse_database(char *filename)
|
||||
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
|
||||
if (!strcmp(name, "DESC")) add_desc(last_id, value);
|
||||
if (!strcmp(name, "FORMAT")) add_format(last_id, value);
|
||||
if (!strcmp(name, "VCD_NAME")) add_vcd_name(last_id, value);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
@@ -424,6 +433,12 @@ char *event_name_from_id(void *_database, int id)
|
||||
return d->i[d->id_to_pos[id]].name;
|
||||
}
|
||||
|
||||
char *event_vcd_name_from_id(void *_database, int id)
|
||||
{
|
||||
database *d = _database;
|
||||
return d->i[d->id_to_pos[id]].vcd_name;
|
||||
}
|
||||
|
||||
int event_id_from_name(void *_database, char *name)
|
||||
{
|
||||
database *d = _database;
|
||||
|
||||
@@ -8,6 +8,7 @@ void list_ids(void *database);
|
||||
void list_groups(void *database);
|
||||
void on_off(void *d, char *item, int *a, int onoff);
|
||||
char *event_name_from_id(void *database, int id);
|
||||
char *event_vcd_name_from_id(void *_database, int id);
|
||||
int event_id_from_name(void *database, char *name);
|
||||
int number_of_ids(void *database);
|
||||
int database_get_ids(void *database, char ***ids);
|
||||
|
||||
@@ -12,7 +12,14 @@
|
||||
#include "logger/logger.h"
|
||||
#include "view/view.h"
|
||||
|
||||
enum var_type {
|
||||
DEFAULT,
|
||||
VCD_FUNCTION,
|
||||
VCD_VARIABLE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum var_type type;
|
||||
char *event;
|
||||
char *arg;
|
||||
char *vcd_name;
|
||||
@@ -44,16 +51,39 @@ void vcd_write_header(vcd_vars *v, int n)
|
||||
"$version\n"
|
||||
" to_vcd\n"
|
||||
"$end\n"
|
||||
"$timescale 1ns $end\n"
|
||||
"$timescale 1ns $end\n") <= 0) abort();
|
||||
|
||||
if (fprintf(out,
|
||||
"$scope module logic $end\n") <= 0) abort();
|
||||
for (i = 0; i < n; i++)
|
||||
if (v[i].type == DEFAULT)
|
||||
if (fprintf(out, "$var wire %d %s %s $end\n",
|
||||
v[i].boolean ? 1 : 64,
|
||||
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
|
||||
if (fprintf(out,
|
||||
"$upscope $end\n") <= 0) abort();
|
||||
|
||||
if (fprintf(out,
|
||||
"$scope module functions $end\n") <= 0) abort();
|
||||
for (i = 0; i < n; i++)
|
||||
if (v[i].type == VCD_FUNCTION)
|
||||
if (fprintf(out, "$var wire %d %s %s $end\n",
|
||||
v[i].boolean ? 1 : 64,
|
||||
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
|
||||
if (fprintf(out,
|
||||
"$upscope $end\n") <= 0) abort();
|
||||
|
||||
if (fprintf(out,
|
||||
"$scope module variables $end\n") <= 0) abort();
|
||||
for (i = 0; i < n; i++)
|
||||
if (fprintf(out, "$var wire %d %s %s $end\n",
|
||||
v[i].boolean ? 1 : 64,
|
||||
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
|
||||
if (v[i].type == VCD_VARIABLE)
|
||||
if (fprintf(out, "$var wire %d %s %s $end\n",
|
||||
v[i].boolean ? 1 : 64,
|
||||
v[i].vcd_name, v[i].vcd_name) <= 0) abort();
|
||||
if (fprintf(out,
|
||||
"$upscope $end\n") <= 0) abort();
|
||||
|
||||
if (fprintf(out,
|
||||
"$upscope $end\n"
|
||||
"$enddefinitions $end\n"
|
||||
"$dumpvars\n") <= 0) abort();
|
||||
|
||||
@@ -194,12 +224,13 @@ void force_stop(int x)
|
||||
}
|
||||
|
||||
vcd_vars *add_var(vcd_vars *vars, int nvars,
|
||||
char *event, char *arg, char *vcd_name, int is_boolean)
|
||||
char *event, char *arg, char *vcd_name, int is_boolean, enum var_type t)
|
||||
{
|
||||
if (nvars % 64 == 0) {
|
||||
vars = realloc(vars, (nvars+64) * sizeof(vcd_vars));
|
||||
if (vars == NULL) abort();
|
||||
}
|
||||
vars[nvars].type = t;
|
||||
vars[nvars].event = event;
|
||||
vars[nvars].arg = arg;
|
||||
vars[nvars].vcd_name = vcd_name;
|
||||
@@ -240,7 +271,7 @@ int main(int n, char **v)
|
||||
char *event = v[++i];
|
||||
char *arg = v[++i];
|
||||
char *vcd_name = v[++i];
|
||||
vars = add_var(vars, nvars, event, arg, vcd_name, 1);
|
||||
vars = add_var(vars, nvars, event, arg, vcd_name, 1, DEFAULT);
|
||||
nvars++;
|
||||
continue;
|
||||
}
|
||||
@@ -248,7 +279,7 @@ int main(int n, char **v)
|
||||
char *event = v[++i];
|
||||
char *arg = v[++i];
|
||||
char *vcd_name = v[++i];
|
||||
vars = add_var(vars, nvars, event, arg, vcd_name, 0);
|
||||
vars = add_var(vars, nvars, event, arg, vcd_name, 0, DEFAULT);
|
||||
nvars++;
|
||||
continue;
|
||||
}
|
||||
@@ -283,20 +314,30 @@ int main(int n, char **v)
|
||||
/* activate all VCD traces */
|
||||
for (i = 0; i < number_of_events; i++) {
|
||||
int is_boolean;
|
||||
enum var_type type;
|
||||
int prefix_length;
|
||||
char *name = event_name_from_id(database, i);
|
||||
char *vcd_name;
|
||||
char *var_prefix = "VCD_VARIABLE_";
|
||||
char *fun_prefix = "VCD_FUNCTION_";
|
||||
if (!strncmp(name, var_prefix, strlen(var_prefix))) {
|
||||
prefix_length = strlen(var_prefix);
|
||||
is_boolean = 0;
|
||||
type = VCD_VARIABLE;
|
||||
} else if (!strncmp(name, fun_prefix, strlen(fun_prefix))) {
|
||||
prefix_length = strlen(fun_prefix);
|
||||
is_boolean = 1;
|
||||
type = VCD_FUNCTION;
|
||||
} else
|
||||
continue;
|
||||
vcd_name = event_vcd_name_from_id(database, i);
|
||||
if (vcd_name == NULL) {
|
||||
vcd_name = name+prefix_length;
|
||||
printf("WARNING: ID %s does not define VCD_NAME in the file %s, using %s\n",
|
||||
name, database_filename, vcd_name);
|
||||
}
|
||||
vars = add_var(vars, nvars,
|
||||
name, "value", name+prefix_length, is_boolean);
|
||||
name, "value", vcd_name, is_boolean, type);
|
||||
nvars++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user