Add support for collapsed/aliased arrays.
Arrays of nets that have all their words collapsed together can become a collapsed array as a whole. Add support for this case in the vvp code generator and runtime.
This commit is contained in:
parent
396ffd1cdd
commit
ed698deeaa
|
|
@ -1070,6 +1070,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
||||||
} else {
|
} else {
|
||||||
/* If this is an isolated word, it uses its
|
/* If this is an isolated word, it uses its
|
||||||
own name. */
|
own name. */
|
||||||
|
assert(word_count == 1);
|
||||||
fprintf(vvp_out, "v%p_%u .net%s%s \"%s\", %d %d, %s;"
|
fprintf(vvp_out, "v%p_%u .net%s%s \"%s\", %d %d, %s;"
|
||||||
" %u drivers%s\n",
|
" %u drivers%s\n",
|
||||||
sig, iword, vec8, datatype_flag,
|
sig, iword, vec8, datatype_flag,
|
||||||
|
|
@ -1081,15 +1082,37 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
||||||
nex_data->net = sig;
|
nex_data->net = sig;
|
||||||
nex_data->net_word = iword;
|
nex_data->net_word = iword;
|
||||||
|
|
||||||
|
} else if (dimensions > 0) {
|
||||||
|
|
||||||
|
/* In this case, we have an alias to an existing
|
||||||
|
signal array. this typically is an instance of
|
||||||
|
port collapsing that the elaborator combined to
|
||||||
|
discover that the entire array can be collapsed,
|
||||||
|
so the word count for the signal and the alias
|
||||||
|
*must* match. */
|
||||||
|
assert(word_count == ivl_signal_array_count(nex_data->net));
|
||||||
|
|
||||||
|
if (iword == 0) {
|
||||||
|
fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s\n",
|
||||||
|
sig, vvp_mangle_name(ivl_signal_basename(sig)),
|
||||||
|
nex_data->net, ivl_signal_basename(nex_data->net));
|
||||||
|
}
|
||||||
|
/* An alias for the individual words? */
|
||||||
|
#if 0
|
||||||
|
fprintf(vvp_out, "v%p_%u .alias%s v%p, %d %d, v%p_%u;\n",
|
||||||
|
sig, iword, datatype_flag, sig,
|
||||||
|
msb, lsb, nex_data->net, nex_data->net_word);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
/* Finally, we may have an alias that is a word
|
||||||
|
connected to another word. Again, this is a
|
||||||
|
case of port collapsing. */
|
||||||
|
|
||||||
assert(word_count == 1);
|
/* For the alias, create a different kind of node
|
||||||
|
that refers to the alias source data instead of
|
||||||
/* Detect that this is an alias of nex_data->net. Create
|
holding our own data. */
|
||||||
a different kind of node that refers to the alias
|
fprintf(vvp_out, "v%p_%u .alias%s \"%s\", %d %d, v%p_%u;\n",
|
||||||
source data instead of holding our own data. */
|
sig, iword, datatype_flag,
|
||||||
fprintf(vvp_out, "v%p_0 .alias%s \"%s\", %d %d, v%p_%u;\n",
|
|
||||||
sig, datatype_flag,
|
|
||||||
vvp_mangle_name(ivl_signal_basename(sig)),
|
vvp_mangle_name(ivl_signal_basename(sig)),
|
||||||
msb, lsb, nex_data->net, nex_data->net_word);
|
msb, lsb, nex_data->net, nex_data->net_word);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,12 @@ declared seperately, this statement collects them together:
|
||||||
the .var or .net statements after this array statement, that have the
|
the .var or .net statements after this array statement, that have the
|
||||||
same "name" are collected, in order, as words.
|
same "name" are collected, in order, as words.
|
||||||
|
|
||||||
|
The syntax below is different, in that it creates an alias for an
|
||||||
|
existing array. The dimensions and storage are taken from the .array
|
||||||
|
at <src>.
|
||||||
|
|
||||||
|
<label> .array "name", <src> ;
|
||||||
|
|
||||||
MEMORY STATEMENTS:
|
MEMORY STATEMENTS:
|
||||||
|
|
||||||
Memories are arrays of words, each word a vvp_vector4_t vector of the
|
Memories are arrays of words, each word a vvp_vector4_t vector of the
|
||||||
|
|
|
||||||
36
vvp/array.cc
36
vvp/array.cc
|
|
@ -465,6 +465,42 @@ void compile_array_port(char*label, char*array, char*addr)
|
||||||
// The input_connect arranges for the array string to be free'ed.
|
// The input_connect arranges for the array string to be free'ed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compile_array_alias(char*label, char*name, char*src)
|
||||||
|
{
|
||||||
|
vvp_array_t mem = array_find(src);
|
||||||
|
assert(mem);
|
||||||
|
|
||||||
|
struct __vpiArray*obj = (struct __vpiArray*)
|
||||||
|
malloc(sizeof (struct __vpiArray));
|
||||||
|
|
||||||
|
obj->base.vpi_type = &vpip_arraymem_rt;
|
||||||
|
obj->scope = vpip_peek_current_scope();
|
||||||
|
obj->name = vpip_name_string(name);
|
||||||
|
obj->array_count = mem->array_count;
|
||||||
|
|
||||||
|
// XXXX Need to set an accurate range of addreses.
|
||||||
|
vpip_make_dec_const(&obj->first_addr, mem->first_addr.value);
|
||||||
|
vpip_make_dec_const(&obj->last_addr, mem->last_addr.value);
|
||||||
|
|
||||||
|
// Share the words with the source array.
|
||||||
|
obj->words = mem->words;
|
||||||
|
|
||||||
|
obj->ports_ = 0;
|
||||||
|
|
||||||
|
assert(array_table);
|
||||||
|
assert(!array_find(label));
|
||||||
|
symbol_value_t v;
|
||||||
|
v.ptr = obj;
|
||||||
|
sym_set_value(array_table, label, v);
|
||||||
|
|
||||||
|
compile_vpi_symbol(label, &obj->base);
|
||||||
|
vpip_attach_to_current_scope(&obj->base);
|
||||||
|
|
||||||
|
free(label);
|
||||||
|
free(name);
|
||||||
|
free(src);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: array.cc,v $
|
* $Log: array.cc,v $
|
||||||
* Revision 1.2 2007/04/10 01:26:16 steve
|
* Revision 1.2 2007/04/10 01:26:16 steve
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,7 @@ extern void compile_real_array(char*label, char*name,
|
||||||
int msb, int lsb);
|
int msb, int lsb);
|
||||||
extern void compile_net_array(char*label, char*name,
|
extern void compile_net_array(char*label, char*name,
|
||||||
int last, int first);
|
int last, int first);
|
||||||
|
extern void compile_array_alias(char*label, char*name, char*src);
|
||||||
|
|
||||||
extern void compile_array_port(char*label, char*name, char*addr);
|
extern void compile_array_port(char*label, char*name, char*addr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,9 @@ statement
|
||||||
| T_LABEL K_ARRAY_PORT T_SYMBOL ',' T_SYMBOL ';'
|
| T_LABEL K_ARRAY_PORT T_SYMBOL ',' T_SYMBOL ';'
|
||||||
{ compile_array_port($1, $3, $5); }
|
{ compile_array_port($1, $3, $5); }
|
||||||
|
|
||||||
|
| T_LABEL K_ARRAY T_STRING ',' T_SYMBOL ';'
|
||||||
|
{ compile_array_alias($1, $3, $5); }
|
||||||
|
|
||||||
/* The .ufunc functor is for implementing user defined functions, or
|
/* The .ufunc functor is for implementing user defined functions, or
|
||||||
other thread code that is automatically invoked if any of the
|
other thread code that is automatically invoked if any of the
|
||||||
bits in the symbols list change. */
|
bits in the symbols list change. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue