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:
Stephen Williams 2007-06-24 18:17:37 -07:00
parent 396ffd1cdd
commit ed698deeaa
5 changed files with 76 additions and 7 deletions

View File

@ -1070,6 +1070,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
} else {
/* If this is an isolated word, it uses its
own name. */
assert(word_count == 1);
fprintf(vvp_out, "v%p_%u .net%s%s \"%s\", %d %d, %s;"
" %u drivers%s\n",
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_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 {
/* 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);
/* Detect that this is an alias of nex_data->net. Create
a different kind of node that refers to the alias
source data instead of holding our own data. */
fprintf(vvp_out, "v%p_0 .alias%s \"%s\", %d %d, v%p_%u;\n",
sig, datatype_flag,
/* For the alias, create a different kind of node
that refers to the alias source data instead of
holding our own data. */
fprintf(vvp_out, "v%p_%u .alias%s \"%s\", %d %d, v%p_%u;\n",
sig, iword, datatype_flag,
vvp_mangle_name(ivl_signal_basename(sig)),
msb, lsb, nex_data->net, nex_data->net_word);
}

View File

@ -380,6 +380,12 @@ declared seperately, this statement collects them together:
the .var or .net statements after this array statement, that have the
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:
Memories are arrays of words, each word a vvp_vector4_t vector of the

View File

@ -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.
}
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 $
* Revision 1.2 2007/04/10 01:26:16 steve

View File

@ -251,6 +251,7 @@ extern void compile_real_array(char*label, char*name,
int msb, int lsb);
extern void compile_net_array(char*label, char*name,
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);

View File

@ -196,6 +196,9 @@ statement
| T_LABEL K_ARRAY_PORT T_SYMBOL ',' T_SYMBOL ';'
{ 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
other thread code that is automatically invoked if any of the
bits in the symbols list change. */