diff --git a/Statement.h b/Statement.h index 68a1f8899..f812928c9 100644 --- a/Statement.h +++ b/Statement.h @@ -210,6 +210,8 @@ class PCallTask : public Statement { NetProc* elaborate_sys(Design*des, NetScope*scope) const; NetProc* elaborate_usr(Design*des, NetScope*scope) const; + NetProc*elaborate_method_(Design*des, NetScope*scope) const; + pform_name_t path_; vector parms_; }; diff --git a/design_dump.cc b/design_dump.cc index cfe54954b..488553938 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1305,12 +1305,12 @@ void NetSTask::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << name_; - if (parms_.count() > 0) { + if (parms_.size() > 0) { o << "("; if (parms_[0]) parms_[0]->dump(o); - for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { + for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { o << ", "; if (parms_[idx]) parms_[idx]->dump(o); diff --git a/elaborate.cc b/elaborate.cc index c777fb65a..7a24cb69b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2908,7 +2908,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const if ((parm_count== 1) && (parms_[0] == 0)) parm_count = 0; - svectoreparms (parm_count); + vectoreparms (parm_count); perm_string name = peek_tail_name(path_); @@ -2987,6 +2987,12 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const NetScope*task = des->find_task(scope, path_); if (task == 0) { + // Maybe this is a method attached to a signal? + if (gn_system_verilog()) { + NetProc*tmp = elaborate_method_(des, scope); + if (tmp) return tmp; + } + cerr << get_fileline() << ": error: Enable of unknown task " << "``" << path_ << "''." << endl; des->errors += 1; @@ -3169,6 +3175,39 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const return block; } +NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const +{ + pform_name_t use_path = path_; + perm_string method_name = peek_tail_name(use_path); + use_path.pop_back(); + + NetNet *net; + const NetExpr *par; + NetEvent *eve; + const NetExpr *ex1, *ex2; + + symbol_search(this, des, scope, use_path, + net, par, eve, ex1, ex2); + + if (net == 0) + return 0; + + // Is this a delete method for dynamic arrays? + if (net->darray_type() && method_name=="delete") { + NetESignal*sig = new NetESignal(net); + + vector argv (1); + argv[0] = sig; + + NetSTask*sys = new NetSTask("$ivl_darray_method$delete", + IVL_SFUNC_AS_TASK_IGNORE, argv); + sys->set_line(*this); + return sys; + } + + return 0; +} + /* * Elaborate a procedural continuous assign. This really looks very * much like other procedural assignments, at this point, but there diff --git a/net_nex_input.cc b/net_nex_input.cc index f1ece6ec7..25b67e95e 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -397,13 +397,13 @@ NexusSet* NetRepeat::nex_input(bool rem_out) */ NexusSet* NetSTask::nex_input(bool rem_out) { - if (parms_.count() == 0) + if (parms_.size() == 0) return new NexusSet; NexusSet*result; if (parms_[0]) result = parms_[0]->nex_input(rem_out); else result = new NexusSet; - for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { + for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]) { NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); diff --git a/netlist.cc b/netlist.cc index b6aaa3da3..42ca44bb3 100644 --- a/netlist.cc +++ b/netlist.cc @@ -2089,7 +2089,7 @@ const NetNet* NetFuncDef::return_sig() const } NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat, - const svector&pa) + const vector&pa) : name_(0), sfunc_as_task_(sfat), parms_(pa) { name_ = lex_strings.add(na); @@ -2098,7 +2098,7 @@ NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat, NetSTask::~NetSTask() { - for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) + for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) delete parms_[idx]; /* The name_ string is perm-allocated in lex_strings. */ @@ -2116,7 +2116,7 @@ ivl_sfunc_as_task_t NetSTask::sfunc_as_task() const unsigned NetSTask::nparms() const { - return parms_.count(); + return parms_.size(); } const NetExpr* NetSTask::parm(unsigned idx) const diff --git a/netlist.h b/netlist.h index d18172868..635e99cd0 100644 --- a/netlist.h +++ b/netlist.h @@ -3191,7 +3191,7 @@ class NetSTask : public NetProc { public: NetSTask(const char*na, ivl_sfunc_as_task_t sfat, - const svector&); + const std::vector&); ~NetSTask(); const char* name() const; @@ -3209,7 +3209,7 @@ class NetSTask : public NetProc { private: const char* name_; ivl_sfunc_as_task_t sfunc_as_task_; - svectorparms_; + std::vectorparms_; }; /* diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index c30fab792..702d14ef9 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1646,8 +1646,29 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) return rc; } +static int show_delete_method(ivl_statement_t net) +{ + show_stmt_file_line(net, "Delete object"); + + unsigned parm_count = ivl_stmt_parm_count(net); + if (parm_count < 1) + return 1; + + ivl_expr_t parm = ivl_stmt_parm(net, 0); + assert(ivl_expr_type(parm) == IVL_EX_SIGNAL); + ivl_signal_t var = ivl_expr_signal(parm); + + fprintf(vvp_out, " %%delete/obj v%p_0;\n", var); + return 0; +} + static int show_system_task_call(ivl_statement_t net) { + const char*stmt_name = ivl_stmt_name(net); + + if (strcmp(stmt_name,"$ivl_darray_method$delete") == 0) + return show_delete_method(net); + show_stmt_file_line(net, "System task call."); draw_vpi_task_call(net); diff --git a/vvp/codes.h b/vvp/codes.h index ff7da1d60..e0bc181fb 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -88,6 +88,7 @@ extern bool of_DEASSIGN(vthread_t thr, vvp_code_t code); extern bool of_DEASSIGN_WR(vthread_t thr, vvp_code_t code); extern bool of_DELAY(vthread_t thr, vvp_code_t code); extern bool of_DELAYX(vthread_t thr, vvp_code_t code); +extern bool of_DELETE_OBJ(vthread_t thr, vvp_code_t code); extern bool of_DISABLE(vthread_t thr, vvp_code_t code); extern bool of_DIV(vthread_t thr, vvp_code_t code); extern bool of_DIV_S(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 37e20397e..1e6f5eef3 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -139,6 +139,7 @@ static const struct opcode_table_s opcode_table[] = { { "%deassign/wr",of_DEASSIGN_WR,1,{OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, + { "%delete/obj",of_DELETE_OBJ,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%div", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%div/s", of_DIV_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%div/wr", of_DIV_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 810e4009f..5f94a2249 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -375,6 +375,11 @@ This is similar to the %delay opcode, except that the parameter selects an index register, which contains the actual delay. This supports run-time calculated delays. +* %delete/obj + +Arrange for the dynamic object at the target label to be deleted. +This has no effect on the object or string stack. + * %disable This instruction terminates threads that are part of a specific @@ -720,7 +725,7 @@ means the following: Create a new array (of int objects) with a size. the is the address of an index variable that contains the computed array size to -use. +use. See also %delete/obj NOTE: For now, assume this is an array of int values. diff --git a/vvp/vthread.cc b/vvp/vthread.cc index a912d6101..0805c2cd9 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2011,6 +2011,21 @@ bool of_DELAYX(vthread_t thr, vvp_code_t cp) return false; } +/* %delete/obj