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 {
|
||||
/* 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
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.
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue