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.
This commit is contained in:
parent
0cd6fbaf41
commit
dec4cd5071
68
elab_expr.cc
68
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.
|
||||
list<NetExpr*>unpacked_indices;
|
||||
list<long> 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;
|
||||
|
|
|
|||
|
|
@ -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<netrange_t> 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<struct_type_t*>(set_data_type_)) {
|
||||
// If this is a struct type, then build the net with the
|
||||
|
|
|
|||
|
|
@ -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: "
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
51
vvp/array.cc
51
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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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} },
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <var-label>
|
||||
*/
|
||||
|
|
@ -5444,6 +5461,23 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/obja <array-label> <index>
|
||||
*/
|
||||
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 <id>
|
||||
*
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 <class TYPE> vvp_darray_atom<TYPE>::~vvp_darray_atom()
|
||||
{
|
||||
}
|
||||
|
|
@ -101,6 +111,32 @@ template class vvp_darray_atom<int16_t>;
|
|||
template class vvp_darray_atom<int32_t>;
|
||||
template class vvp_darray_atom<int64_t>;
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 TYPE> class vvp_darray_atom : public vvp_darray {
|
||||
|
|
@ -86,6 +89,19 @@ class vvp_darray_string : public vvp_darray {
|
|||
std::vector<std::string> 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<vvp_object_t> array_;
|
||||
};
|
||||
|
||||
class vvp_queue : public vvp_darray {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue