From dec4cd5071fa544abc3e4c2bd709ccacf60e0bba Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 29 Aug 2014 20:31:51 -0700 Subject: [PATCH] Handle arrays of class objects. This goes all the way down to the vvp level, where we create support for arrays of objects, generate the new code in the -tvvp code generator, and elaborate the arrays in the first place. --- elab_expr.cc | 68 +++++++++++++++++++++++++++++++++++++++++-- elab_sig.cc | 9 +++--- elaborate.cc | 8 +++-- tgt-vvp/eval_expr.c | 12 +++++++- tgt-vvp/eval_object.c | 21 +++++++++++-- tgt-vvp/stmt_assign.c | 14 ++++++++- tgt-vvp/vvp_scope.c | 4 +++ vvp/array.cc | 51 ++++++++++++++++++++++++++++++++ vvp/array.h | 3 ++ vvp/codes.h | 3 ++ vvp/compile.cc | 3 ++ vvp/compile.h | 2 ++ vvp/lexor.lex | 1 + vvp/parse.y | 5 +++- vvp/vthread.cc | 55 ++++++++++++++++++++++++++++++++++ vvp/vvp_darray.cc | 36 +++++++++++++++++++++++ vvp/vvp_darray.h | 16 ++++++++++ 17 files changed, 296 insertions(+), 15 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 30ade72ac..da4bf6c82 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3113,8 +3113,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, - ivl_type_t ntype, unsigned) const + ivl_type_t ntype, unsigned flags) const { + bool need_const = NEED_CONST & flags; + NetNet* net = 0; const NetExpr*par = 0; NetEvent* eve = 0; @@ -3185,7 +3187,69 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, } ivl_assert(*this, ntype->type_compatible(net->net_type())); - NetESignal*tmp = new NetESignal(net); + const name_component_t&use_comp = path_.back(); + + if (debug_elaborate) { + cerr << get_fileline() << ": PEIdent::elaborate_expr: " + << "Typed ident " << net->name() + << " with " << use_comp.index.size() << " indices" + << " and " << net->unpacked_dimensions() << " expected." + << endl; + } + + if (net->unpacked_dimensions() != use_comp.index.size()) { + cerr << get_fileline() << ": sorry: " + << "Net " << net->name() + << " expects " << net->unpacked_dimensions() + << ", but got " << use_comp.index.size() << "." + << endl; + des->errors += 1; + + NetESignal*tmp = new NetESignal(net); + tmp->set_line(*this); + return tmp; + } + + if (net->unpacked_dimensions() == 0) { + NetESignal*tmp = new NetESignal(net); + tmp->set_line(*this); + return tmp; + } + + // Convert a set of index expressions to a single expression + // that addresses the canonical element. + listunpacked_indices; + list unpacked_indices_const; + indices_flags idx_flags; + indices_to_expressions(des, scope, this, + use_comp.index, net->unpacked_dimensions(), + need_const, + idx_flags, + unpacked_indices, + unpacked_indices_const); + + NetExpr*canon_index = 0; + + if (idx_flags.invalid) { + // Nothing to do + + } else if (idx_flags.undefined) { + cerr << get_fileline() << ": warning: " + << "returning 'bx for undefined array access " + << net->name() << as_indices(unpacked_indices) + << "." << endl; + + } else if (idx_flags.variable) { + ivl_assert(*this, unpacked_indices.size() == net->unpacked_dimensions()); + canon_index = normalize_variable_unpacked(net, unpacked_indices); + + } else { + ivl_assert(*this, unpacked_indices_const.size() == net->unpacked_dimensions()); + canon_index = normalize_variable_unpacked(net, unpacked_indices_const); + } + + ivl_assert(*this, canon_index); + NetESignal*tmp = new NetESignal(net, canon_index); tmp->set_line(*this); return tmp; diff --git a/elab_sig.cc b/elab_sig.cc index e88689a14..37c10f0b8 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1222,13 +1222,12 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const } ivl_assert(*this, use_type); if (debug_elaborate) { - cerr << get_fileline() << ": debug: " + cerr << get_fileline() << ": PWire::elaborate_sig: " << "Create class instance signal " << wtype - << " " << name_ << endl; + << " " << packed_dimensions << name_ << unpacked_dimensions << endl; } - // (No arrays of classes) - list use_unpacked; - sig = new NetNet(scope, name_, wtype, use_unpacked, use_type); + + sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type); } else if (struct_type_t*struct_type = dynamic_cast(set_data_type_)) { // If this is a struct type, then build the net with the diff --git a/elaborate.cc b/elaborate.cc index a09a3403f..c8e801a5f 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -4600,15 +4600,19 @@ NetProc* PForeach::elaborate(Design*des, NetScope*scope) const if (debug_elaborate) { cerr << get_fileline() << ": PForeach::elaborate: " << "Scan array " << array_sig->name() - << " with " << array_sig->unpacked_dims().size() << " unpacked" - << " and " << array_sig->packed_dims().size() + << " of " << array_sig->data_type() + << " with " << array_sig->unpacked_dimensions() << " unpacked" + << " and " << array_sig->packed_dimensions() << " packed dimensions." << endl; } + // Classic arrays are processed this way. if (array_sig->data_type()==IVL_VT_BOOL) return elaborate_static_array_(des, scope, array_sig); if (array_sig->data_type()==IVL_VT_LOGIC) return elaborate_static_array_(des, scope, array_sig); + if (array_sig->unpacked_dimensions() >= index_vars_.size()) + return elaborate_static_array_(des, scope, array_sig); if (index_vars_.size() != 1) { cerr << get_fileline() << ": sorry: " diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 7d8ed5d25..d4028dddf 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -519,7 +519,17 @@ static struct vector_info draw_binary_expr_eq_class(ivl_expr_t expr) } if (ivl_expr_type(re) == IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_SIGNAL) { - fprintf(vvp_out, " %%test_nul v%p_0;\n", ivl_expr_signal(le)); + ivl_signal_t sig = ivl_expr_signal(le); + + if (ivl_signal_dimensions(sig) == 0) { + fprintf(vvp_out, " %%test_nul v%p_0;\n", sig); + } else { + ivl_expr_t word_ex = ivl_expr_oper1(le); + int word_ix = allocate_word(); + draw_eval_expr_into_integer(word_ex, word_ix); + fprintf(vvp_out, " %%test_nula v%p, %d;\n", sig, word_ix); + clr_word(word_ix); + } fprintf(vvp_out, " %%mov %u, 4, 1;\n", res.base); if (ivl_expr_opcode(expr) == 'n') fprintf(vvp_out, " %%inv %u, 1;\n", res.base); diff --git a/tgt-vvp/eval_object.c b/tgt-vvp/eval_object.c index 01019a0a6..883eeeb57 100644 --- a/tgt-vvp/eval_object.c +++ b/tgt-vvp/eval_object.c @@ -195,10 +195,25 @@ static int eval_object_shallowcopy(ivl_expr_t ex) return 0; } -static int eval_object_signal(ivl_expr_t ex) +static int eval_object_signal(ivl_expr_t expr) { - ivl_signal_t sig = ivl_expr_signal(ex); - fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); + ivl_signal_t sig = ivl_expr_signal(expr); + + /* Simple case: This is a simple variable. Generate a load + statement to load the string into the stack. */ + if (ivl_signal_dimensions(sig) == 0) { + fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); + return 0; + } + + /* There is a word select expression, so load the index into a + register and load from the array. */ + ivl_expr_t word_ex = ivl_expr_oper1(expr); + int word_ix = allocate_word(); + draw_eval_expr_into_integer(word_ex, word_ix); + fprintf(vvp_out, " %%load/obja v%p, %d;\n", sig, word_ix); + clr_word(word_ix); + return 0; } diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index c05bd1fe1..74ffde30c 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1066,7 +1066,19 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net) as an object and assign the entire object to the variable. */ errors += draw_eval_object(rval); - fprintf(vvp_out, " %%store/obj v%p_0;\n", sig); + + if (ivl_signal_array_count(sig) > 1) { + unsigned ix; + ivl_expr_t aidx = ivl_lval_idx(lval); + + draw_eval_expr_into_integer(aidx, (ix = allocate_word())); + fprintf(vvp_out, " %%store/obja v%p, %u;\n", sig, ix); + clr_word(ix); + + } else { + /* Not an array, so no index expression */ + fprintf(vvp_out, " %%store/obj v%p_0;\n", sig); + } } return errors; diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index a41db91b3..b2779f379 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -469,6 +469,10 @@ static void draw_reg_in_scope(ivl_signal_t sig) datatype_flag = "/str"; vector_dims = 0; break; + case IVL_VT_CLASS: + datatype_flag = "/obj"; + vector_dims = 0; + break; default: break; } diff --git a/vvp/array.cc b/vvp/array.cc index 25bfdbf3d..396b7effe 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -1055,6 +1055,18 @@ void array_set_word(vvp_array_t arr, unsigned address, const string&val) array_word_change(arr, address); } +void array_set_word(vvp_array_t arr, unsigned address, const vvp_object_t&val) +{ + assert(arr->vals != 0); + assert(arr->nets == 0); + + if (address >= arr->vals->get_size()) + return; + + arr->vals->set_word(address, val); + array_word_change(arr, address); +} + vvp_vector4_t array_get_word(vvp_array_t arr, unsigned address) { if (arr->vals4) { @@ -1129,6 +1141,28 @@ double array_get_word_r(vvp_array_t arr, unsigned address) } +void array_get_word_obj(vvp_array_t arr, unsigned address, vvp_object_t&val) +{ + if (arr->vals) { + assert(arr->vals4 == 0); + assert(arr->nets == 0); + // In this context, address out of bounds returns 0.0 + // instead of an error. + if (address >= arr->vals->get_size()) { + val = vvp_object_t(); + return; + } + + arr->vals->get_word(address, val); + return; + } + + assert(arr->nets); + // Arrays of string nets not implemented! + assert(0); + return; +} + string array_get_word_str(vvp_array_t arr, unsigned address) { if (arr->vals) { @@ -1354,6 +1388,23 @@ void compile_string_array(char*label, char*name, int last, int first) delete[] name; } +void compile_object_array(char*label, char*name, int last, int first) +{ + vpiHandle obj = vpip_make_array(label, name, first, last, true); + + struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); + + /* Make the words. */ + arr->vals = new vvp_darray_object(arr->array_count); + arr->vals_width = 1; + + count_real_arrays += 1; + count_real_array_words += arr->array_count; + + free(label); + delete[] name; +} + void compile_net_array(char*label, char*name, int last, int first) { // At this point we don't know the array data type, so we diff --git a/vvp/array.h b/vvp/array.h index 322852408..d1766ed15 100644 --- a/vvp/array.h +++ b/vvp/array.h @@ -45,9 +45,12 @@ extern void array_set_word(vvp_array_t arr, unsigned idx, double val); extern void array_set_word(vvp_array_t arr, unsigned idx, const std::string&val); +extern void array_set_word(vvp_array_t arr, unsigned idx, + const vvp_object_t&val); extern vvp_vector4_t array_get_word(vvp_array_t array, unsigned address); extern double array_get_word_r(vvp_array_t array, unsigned address); +extern void array_get_word_obj(vvp_array_t array, unsigned address, vvp_object_t&val); extern std::string array_get_word_str(vvp_array_t array, unsigned address); /* VPI hooks */ diff --git a/vvp/codes.h b/vvp/codes.h index d439bf2e0..bbb555c7d 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -133,6 +133,7 @@ extern bool of_LOAD_REAL(vthread_t thr, vvp_code_t code); extern bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t code); extern bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t code); extern bool of_LOAD_OBJ(vthread_t thr, vvp_code_t code); +extern bool of_LOAD_OBJA(vthread_t thr, vvp_code_t code); extern bool of_LOAD_STR(vthread_t thr, vvp_code_t code); extern bool of_LOAD_STRA(vthread_t thr, vvp_code_t code); extern bool of_LOAD_VEC(vthread_t thr, vvp_code_t code); @@ -203,6 +204,7 @@ extern bool of_STORE_QB_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_QF_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_QF_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code); +extern bool of_STORE_OBJA(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t code); @@ -217,6 +219,7 @@ extern bool of_SUBI(vthread_t thr, vvp_code_t code); extern bool of_SUBSTR(vthread_t thr, vvp_code_t code); extern bool of_SUBSTR_V(vthread_t thr, vvp_code_t code); extern bool of_TEST_NUL(vthread_t thr, vvp_code_t code); +extern bool of_TEST_NULA(vthread_t thr, vvp_code_t code); extern bool of_VPI_CALL(vthread_t thr, vvp_code_t code); extern bool of_WAIT(vthread_t thr, vvp_code_t code); extern bool of_WAIT_FORK(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 4dac7f1de..4115853be 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -180,6 +180,7 @@ static const struct opcode_table_s opcode_table[] = { { "%load/dar/r", of_LOAD_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE}}, { "%load/dar/str",of_LOAD_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%load/obj", of_LOAD_OBJ, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%load/obja", of_LOAD_OBJA,2,{OA_ARR_PTR, OA_BIT1, OA_NONE} }, { "%load/real", of_LOAD_REAL,1,{OA_VPI_PTR, OA_NONE, OA_NONE} }, { "%load/str", of_LOAD_STR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%load/stra", of_LOAD_STRA,2,{OA_ARR_PTR, OA_BIT1, OA_NONE} }, @@ -246,6 +247,7 @@ static const struct opcode_table_s opcode_table[] = { { "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%store/obja", of_STORE_OBJA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} }, { "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%store/prop/str",of_STORE_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} }, @@ -264,6 +266,7 @@ static const struct opcode_table_s opcode_table[] = { { "%substr", of_SUBSTR, 2,{OA_BIT1, OA_BIT2, OA_NONE} }, { "%substr/v",of_SUBSTR_V,3,{OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%test_nul", of_TEST_NUL, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%test_nula", of_TEST_NULA,2,{OA_ARR_PTR, OA_BIT1, OA_NONE} }, { "%wait", of_WAIT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%wait/fork",of_WAIT_FORK,0,{OA_NONE, OA_NONE, OA_NONE} }, { "%xnor", of_XNOR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, diff --git a/vvp/compile.h b/vvp/compile.h index c385e76f0..48b4e6247 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -373,6 +373,8 @@ extern void compile_real_array(char*label, char*name, int last, int first); extern void compile_string_array(char*label, char*name, int last, int first); +extern void compile_object_array(char*label, char*name, + int last, int first); extern void compile_net_array(char*label, char*name, int last, int first); extern void compile_array_alias(char*label, char*name, char*src); diff --git a/vvp/lexor.lex b/vvp/lexor.lex index e197928bf..58848bd76 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -124,6 +124,7 @@ static char* strdupnew(char const *str) ".array/2s" { return K_ARRAY_2S; } ".array/2u" { return K_ARRAY_2U; } ".array/i" { return K_ARRAY_I; } +".array/obj" { return K_ARRAY_OBJ; } ".array/real" { return K_ARRAY_R; } ".array/s" { return K_ARRAY_S; } ".array/str" { return K_ARRAY_STR; } diff --git a/vvp/parse.y b/vvp/parse.y index 2a9753e00..97e5e8665 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -77,7 +77,7 @@ static struct __vpiModPath*modpath_dst = 0; %token K_ARITH_MOD_R K_ARITH_MOD_S %token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R %token K_ARITH_SUM K_ARITH_SUM_R K_ARITH_POW K_ARITH_POW_R K_ARITH_POW_S -%token K_ARRAY K_ARRAY_2U K_ARRAY_2S K_ARRAY_I K_ARRAY_R K_ARRAY_S K_ARRAY_STR K_ARRAY_PORT +%token K_ARRAY K_ARRAY_2U K_ARRAY_2S K_ARRAY_I K_ARRAY_OBJ K_ARRAY_R K_ARRAY_S K_ARRAY_STR K_ARRAY_PORT %token K_CAST_INT K_CAST_REAL K_CAST_REAL_S K_CAST_2 %token K_CLASS %token K_CMP_EEQ K_CMP_EQ K_CMP_EQX K_CMP_EQZ @@ -234,6 +234,9 @@ statement | T_LABEL K_ARRAY_STR T_STRING ',' signed_t_number signed_t_number ';' { compile_string_array($1, $3, $5, $6); } + | T_LABEL K_ARRAY_OBJ T_STRING ',' signed_t_number signed_t_number ';' + { compile_object_array($1, $3, $5, $6); } + | T_LABEL K_ARRAY T_STRING ',' signed_t_number signed_t_number ';' { compile_net_array($1, $3, $5, $6); } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 3a83e20c4..db1d9e08a 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -3531,6 +3531,23 @@ bool of_LOAD_OBJ(vthread_t thr, vvp_code_t cp) return true; } +bool of_LOAD_OBJA(vthread_t thr, vvp_code_t cp) +{ + unsigned idx = cp->bit_idx[0]; + unsigned adr = thr->words[idx].w_int; + vvp_object_t word; + + /* The result is 0.0 if the address is undefined. */ + if (thr_get_bit(thr, 4) == BIT4_1) { + ; // Return nil + } else { + array_get_word_obj(cp->array, adr, word); + } + + thr->push_object(word); + return true; +} + /* * %load/real */ @@ -5444,6 +5461,23 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp) return true; } +/* + * %store/obja + */ +bool of_STORE_OBJA(vthread_t thr, vvp_code_t cp) +{ + unsigned idx = cp->bit_idx[0]; + unsigned adr = thr->words[idx].w_int; + + vvp_object_t val; + thr->pop_object(val); + + array_set_word(cp->array, adr, val); + + return true; +} + + /* * %store/prop/obj * @@ -5798,6 +5832,27 @@ bool of_TEST_NUL(vthread_t thr, vvp_code_t cp) return true; } +bool of_TEST_NULA(vthread_t thr, vvp_code_t cp) +{ + unsigned idx = cp->bit_idx[0]; + unsigned adr = thr->words[idx].w_int; + vvp_object_t word; + + /* If the address is undefined, return true. */ + if (thr_get_bit(thr, 4) == BIT4_1) { + thr_put_bit(thr, 4, BIT4_1); + return true; + } + + array_get_word_obj(cp->array, adr, word); + if (word.test_nil()) + thr_put_bit(thr, 4, BIT4_1); + else + thr_put_bit(thr, 4, BIT4_0); + + return true; +} + bool of_VPI_CALL(vthread_t thr, vvp_code_t cp) { vpip_execute_vpi_call(thr, cp->handle); diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index 9e3e27a8e..247bc0722 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -43,6 +43,11 @@ void vvp_darray::set_word(unsigned, const string&) cerr << "XXXX set_word(string) not implemented for " << typeid(*this).name() << endl; } +void vvp_darray::set_word(unsigned, const vvp_object_t&) +{ + cerr << "XXXX set_word(vvp_object_t) not implemented for " << typeid(*this).name() << endl; +} + void vvp_darray::get_word(unsigned, vvp_vector4_t&) { cerr << "XXXX get_word(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl; @@ -58,6 +63,11 @@ void vvp_darray::get_word(unsigned, string&) cerr << "XXXX get_word(string) not implemented for " << typeid(*this).name() << endl; } +void vvp_darray::get_word(unsigned, vvp_object_t&) +{ + cerr << "XXXX get_word(vvp_object_t) not implemented for " << typeid(*this).name() << endl; +} + template vvp_darray_atom::~vvp_darray_atom() { } @@ -101,6 +111,32 @@ template class vvp_darray_atom; template class vvp_darray_atom; template class vvp_darray_atom; +vvp_darray_object::~vvp_darray_object() +{ +} + +size_t vvp_darray_object::get_size() const +{ + return array_.size(); +} + +void vvp_darray_object::set_word(unsigned adr, const vvp_object_t&value) +{ + if (adr >= array_.size()) + return; + array_[adr] = value; +} + +void vvp_darray_object::get_word(unsigned adr, vvp_object_t&value) +{ + if (adr >= array_.size()) { + value = vvp_object_t(); + return; + } + + value = array_[adr]; +} + vvp_darray_real::~vvp_darray_real() { } diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index 62f4797b8..54e65ae6c 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -42,6 +42,9 @@ class vvp_darray : public vvp_object { virtual void set_word(unsigned adr, const std::string&value); virtual void get_word(unsigned adr, std::string&value); + + virtual void set_word(unsigned adr, const vvp_object_t&value); + virtual void get_word(unsigned adr, vvp_object_t&value); }; template class vvp_darray_atom : public vvp_darray { @@ -86,6 +89,19 @@ class vvp_darray_string : public vvp_darray { std::vector array_; }; +class vvp_darray_object : public vvp_darray { + + public: + inline vvp_darray_object(size_t siz) : array_(siz) { } + ~vvp_darray_object(); + + size_t get_size(void) const; + void set_word(unsigned adr, const vvp_object_t&value); + void get_word(unsigned adr, vvp_object_t&value); + + private: + std::vector array_; +}; class vvp_queue : public vvp_darray {