Implement support for net arrays.
This commit is contained in:
parent
0018cb38b0
commit
9b19e3bcf2
11
vvp/array.cc
11
vvp/array.cc
|
|
@ -883,9 +883,10 @@ vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address)
|
||||||
// width by looking at a word that we know is present.
|
// width by looking at a word that we know is present.
|
||||||
assert(arr->array_count > 0);
|
assert(arr->array_count > 0);
|
||||||
vpiHandle word = arr->nets[0];
|
vpiHandle word = arr->nets[0];
|
||||||
|
assert(word);
|
||||||
struct __vpiSignal*vsig = vpip_signal_from_handle(word);
|
struct __vpiSignal*vsig = vpip_signal_from_handle(word);
|
||||||
assert(vsig);
|
assert(vsig);
|
||||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (vsig->node->fun);
|
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (vsig->node->fil);
|
||||||
assert(sig);
|
assert(sig);
|
||||||
return vvp_vector4_t(sig->value_size(), BIT4_X);
|
return vvp_vector4_t(sig->value_size(), BIT4_X);
|
||||||
}
|
}
|
||||||
|
|
@ -893,7 +894,7 @@ vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address)
|
||||||
vpiHandle word = arr->nets[address];
|
vpiHandle word = arr->nets[address];
|
||||||
struct __vpiSignal*vsig = vpip_signal_from_handle(word);
|
struct __vpiSignal*vsig = vpip_signal_from_handle(word);
|
||||||
assert(vsig);
|
assert(vsig);
|
||||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (vsig->node->fun);
|
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (vsig->node->fil);
|
||||||
assert(sig);
|
assert(sig);
|
||||||
|
|
||||||
vvp_vector4_t val = sig->vec4_value();
|
vvp_vector4_t val = sig->vec4_value();
|
||||||
|
|
@ -989,7 +990,7 @@ void array_alias_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
||||||
array->nets[addr] = word;
|
array->nets[addr] = word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word)
|
||||||
{
|
{
|
||||||
assert(addr < array->array_count);
|
assert(addr < array->array_count);
|
||||||
assert(array->nets);
|
assert(array->nets);
|
||||||
|
|
@ -998,7 +999,7 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
||||||
if (struct __vpiSignal*sig = vpip_signal_from_handle(word)) {
|
if (struct __vpiSignal*sig = vpip_signal_from_handle(word)) {
|
||||||
vvp_net_t*net = sig->node;
|
vvp_net_t*net = sig->node;
|
||||||
assert(net);
|
assert(net);
|
||||||
vvp_vpi_callback*fun = dynamic_cast<vvp_vpi_callback*>(net->fun);
|
vvp_vpi_callback*fun = dynamic_cast<vvp_vpi_callback*>(net->fil);
|
||||||
assert(fun);
|
assert(fun);
|
||||||
fun->attach_as_word(array, addr);
|
fun->attach_as_word(array, addr);
|
||||||
sig->is_netarray = 1;
|
sig->is_netarray = 1;
|
||||||
|
|
@ -1010,7 +1011,7 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
||||||
if (struct __vpiRealVar*sig = (struct __vpiRealVar*)word) {
|
if (struct __vpiRealVar*sig = (struct __vpiRealVar*)word) {
|
||||||
vvp_net_t*net = sig->net;
|
vvp_net_t*net = sig->net;
|
||||||
assert(net);
|
assert(net);
|
||||||
vvp_vpi_callback*fun = dynamic_cast<vvp_vpi_callback*>(net->fun);
|
vvp_vpi_callback*fun = dynamic_cast<vvp_vpi_callback*>(net->fil);
|
||||||
assert(fun);
|
assert(fun);
|
||||||
fun->attach_as_word(array, addr);
|
fun->attach_as_word(array, addr);
|
||||||
sig->is_netarray = 1;
|
sig->is_netarray = 1;
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ extern vpiHandle array_index_iterate(int code, vpiHandle ref);
|
||||||
|
|
||||||
extern void array_word_change(vvp_array_t array, unsigned long addr);
|
extern void array_word_change(vvp_array_t array, unsigned long addr);
|
||||||
|
|
||||||
extern void array_attach_word(vvp_array_t array, unsigned long addr,
|
extern void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word);
|
||||||
vpiHandle word);
|
|
||||||
extern void array_alias_word(vvp_array_t array, unsigned long addr,
|
extern void array_alias_word(vvp_array_t array, unsigned long addr,
|
||||||
vpiHandle word);
|
vpiHandle word);
|
||||||
|
|
||||||
|
|
|
||||||
85
vvp/words.cc
85
vvp/words.cc
|
|
@ -212,8 +212,9 @@ class __compile_net_resolv : public resolv_list_s {
|
||||||
* references into the net.
|
* references into the net.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void __compile_net2(vvp_net_t*node, char*my_label, char*name,
|
static void __compile_net2(vvp_net_t*node, vvp_array_t array,
|
||||||
int msb, int lsb,
|
char*my_label, char*name,
|
||||||
|
int msb, int lsb, unsigned array_addr,
|
||||||
bool signed_flag, bool net8_flag, bool local_flag)
|
bool signed_flag, bool net8_flag, bool local_flag)
|
||||||
{
|
{
|
||||||
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
|
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
|
||||||
|
|
@ -237,10 +238,13 @@ static void __compile_net2(vvp_net_t*node, char*my_label, char*name,
|
||||||
compile_vpi_symbol(my_label, obj);
|
compile_vpi_symbol(my_label, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj) vpip_attach_to_current_scope(obj);
|
if (array)
|
||||||
|
array_attach_word(array, array_addr, obj);
|
||||||
|
else if (obj)
|
||||||
|
vpip_attach_to_current_scope(obj);
|
||||||
|
|
||||||
free(my_label);
|
free(my_label);
|
||||||
delete[] name;
|
if (name) delete[] name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __compile_net(char*label,
|
static void __compile_net(char*label,
|
||||||
|
|
@ -249,8 +253,10 @@ static void __compile_net(char*label,
|
||||||
bool signed_flag, bool net8_flag, bool local_flag,
|
bool signed_flag, bool net8_flag, bool local_flag,
|
||||||
unsigned argc, struct symb_s*argv)
|
unsigned argc, struct symb_s*argv)
|
||||||
{
|
{
|
||||||
// XXXX Forgot how to implement net arrays...
|
vvp_array_t array = array_label? array_find(array_label) : 0;
|
||||||
assert(array_label == 0);
|
assert(array_label ? array!=0 : true);
|
||||||
|
|
||||||
|
if (array_label) free(array_label);
|
||||||
|
|
||||||
assert(argc == 1);
|
assert(argc == 1);
|
||||||
vvp_net_t*node = vvp_net_lookup(argv[0].text);
|
vvp_net_t*node = vvp_net_lookup(argv[0].text);
|
||||||
|
|
@ -261,6 +267,7 @@ static void __compile_net(char*label,
|
||||||
node = create_constant_node(label, argv[0].text);
|
node = create_constant_node(label, argv[0].text);
|
||||||
}
|
}
|
||||||
if (node == 0) {
|
if (node == 0) {
|
||||||
|
assert(array==0);
|
||||||
__compile_net_resolv*res = new __compile_net_resolv(argv[0].text,
|
__compile_net_resolv*res = new __compile_net_resolv(argv[0].text,
|
||||||
label, name, msb, lsb,
|
label, name, msb, lsb,
|
||||||
signed_flag, net8_flag, local_flag);
|
signed_flag, net8_flag, local_flag);
|
||||||
|
|
@ -269,14 +276,8 @@ static void __compile_net(char*label,
|
||||||
}
|
}
|
||||||
assert(node);
|
assert(node);
|
||||||
|
|
||||||
if (name) {
|
__compile_net2(node, array, label, name, msb, lsb, array_addr,
|
||||||
__compile_net2(node, label, name, msb, lsb,
|
signed_flag, net8_flag, local_flag);
|
||||||
signed_flag, net8_flag, local_flag);
|
|
||||||
} else {
|
|
||||||
free(label);
|
|
||||||
if (name) delete[] name;
|
|
||||||
if (array_label) free(array_label);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(argv);
|
free(argv);
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +289,7 @@ bool __compile_net_resolv::resolve(bool msg_flag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__compile_net2(node, my_label_, name_, msb_, lsb_, signed_flag_, net8_flag_, local_flag_);
|
__compile_net2(node, 0, my_label_, name_, msb_, lsb_, 0, signed_flag_, net8_flag_, local_flag_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,8 +334,9 @@ class __compile_real_net_resolv : public resolv_list_s {
|
||||||
bool local_flag_;
|
bool local_flag_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __compile_real_net2(vvp_net_t*node, char*my_label, char*name,
|
static void __compile_real_net2(vvp_net_t*node, vvp_array_t array,
|
||||||
bool local_flag)
|
char*my_label, char*name,
|
||||||
|
unsigned array_addr, bool local_flag)
|
||||||
{
|
{
|
||||||
vvp_wire_base*fil = dynamic_cast<vvp_wire_base*> (node->fil);
|
vvp_wire_base*fil = dynamic_cast<vvp_wire_base*> (node->fil);
|
||||||
|
|
||||||
|
|
@ -349,10 +351,13 @@ static void __compile_real_net2(vvp_net_t*node, char*my_label, char*name,
|
||||||
compile_vpi_symbol(my_label, obj);
|
compile_vpi_symbol(my_label, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj) vpip_attach_to_current_scope(obj);
|
if (array)
|
||||||
|
array_attach_word(array, array_addr, obj);
|
||||||
|
else if (obj)
|
||||||
|
vpip_attach_to_current_scope(obj);
|
||||||
|
|
||||||
free(my_label);
|
free(my_label);
|
||||||
delete[]name;
|
if (name) delete[]name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __compile_real(char*label, char*name,
|
static void __compile_real(char*label, char*name,
|
||||||
|
|
@ -360,12 +365,10 @@ static void __compile_real(char*label, char*name,
|
||||||
int msb, int lsb, bool local_flag,
|
int msb, int lsb, bool local_flag,
|
||||||
unsigned argc, struct symb_s*argv)
|
unsigned argc, struct symb_s*argv)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
vvp_array_t array = array_label ? array_find(array_label) : 0;
|
vvp_array_t array = array_label ? array_find(array_label) : 0;
|
||||||
assert(array_label ? array!=0 : true);
|
assert(array_label ? array!=0 : true);
|
||||||
#endif
|
|
||||||
// XXXX Forgot how to implement net arrays...
|
if (array_label) free(array_label);
|
||||||
assert(array_label == 0);
|
|
||||||
|
|
||||||
assert(argc == 1);
|
assert(argc == 1);
|
||||||
vvp_net_t*node = vvp_net_lookup(argv[0].text);
|
vvp_net_t*node = vvp_net_lookup(argv[0].text);
|
||||||
|
|
@ -376,6 +379,7 @@ static void __compile_real(char*label, char*name,
|
||||||
node = create_constant_node(label, argv[0].text);
|
node = create_constant_node(label, argv[0].text);
|
||||||
}
|
}
|
||||||
if (node == 0) {
|
if (node == 0) {
|
||||||
|
assert(array==0);
|
||||||
__compile_real_net_resolv*res
|
__compile_real_net_resolv*res
|
||||||
= new __compile_real_net_resolv(argv[0].text, label,
|
= new __compile_real_net_resolv(argv[0].text, label,
|
||||||
name, local_flag);
|
name, local_flag);
|
||||||
|
|
@ -384,38 +388,7 @@ static void __compile_real(char*label, char*name,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(node);
|
assert(node);
|
||||||
assert(name);
|
__compile_real_net2(node, array, label, name, array_addr, local_flag);
|
||||||
__compile_real_net2(node, label, name, local_flag);
|
|
||||||
#if 0
|
|
||||||
vvp_fun_signal_real*fun = new vvp_fun_signal_real_sa;
|
|
||||||
net->fun = fun;
|
|
||||||
|
|
||||||
/* Add the label into the functor symbol table. */
|
|
||||||
define_functor_symbol(label, net);
|
|
||||||
|
|
||||||
assert(argc == 1);
|
|
||||||
|
|
||||||
/* Connect the source to my input. */
|
|
||||||
inputs_connect(net, 1, argv);
|
|
||||||
|
|
||||||
vpiHandle obj = 0;
|
|
||||||
if (! local_flag) {
|
|
||||||
/* Make the vpiHandle for the reg. */
|
|
||||||
obj = vpip_make_real_var(name, net);
|
|
||||||
/* This attaches the label to the vpiHandle */
|
|
||||||
compile_vpi_symbol(label, obj);
|
|
||||||
}
|
|
||||||
/* If this is an array word, then attach it to the
|
|
||||||
array. Otherwise, attach it to the current scope. */
|
|
||||||
if (array)
|
|
||||||
array_attach_word(array, array_addr, obj);
|
|
||||||
else if (obj)
|
|
||||||
vpip_attach_to_current_scope(obj);
|
|
||||||
free(label);
|
|
||||||
if (name) delete[] name;
|
|
||||||
if (array_label) free(array_label);
|
|
||||||
free(argv);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __compile_real_net_resolv::resolve(bool msg_flag)
|
bool __compile_real_net_resolv::resolve(bool msg_flag)
|
||||||
|
|
@ -427,7 +400,7 @@ bool __compile_real_net_resolv::resolve(bool msg_flag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__compile_real_net2(node, my_label_, name_, local_flag_);
|
__compile_real_net2(node, 0, my_label_, name_, 0, local_flag_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue