Support the delete method for objects.
This commit is contained in:
parent
d0e6b24ca2
commit
18714e2efd
|
|
@ -210,6 +210,8 @@ class PCallTask : public Statement {
|
||||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||||
NetProc* elaborate_usr(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_;
|
pform_name_t path_;
|
||||||
vector<PExpr*> parms_;
|
vector<PExpr*> parms_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1305,12 +1305,12 @@ void NetSTask::dump(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << name_;
|
o << setw(ind) << "" << name_;
|
||||||
|
|
||||||
if (parms_.count() > 0) {
|
if (parms_.size() > 0) {
|
||||||
o << "(";
|
o << "(";
|
||||||
if (parms_[0])
|
if (parms_[0])
|
||||||
parms_[0]->dump(o);
|
parms_[0]->dump(o);
|
||||||
|
|
||||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||||
o << ", ";
|
o << ", ";
|
||||||
if (parms_[idx])
|
if (parms_[idx])
|
||||||
parms_[idx]->dump(o);
|
parms_[idx]->dump(o);
|
||||||
|
|
|
||||||
41
elaborate.cc
41
elaborate.cc
|
|
@ -2908,7 +2908,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
|
||||||
if ((parm_count== 1) && (parms_[0] == 0))
|
if ((parm_count== 1) && (parms_[0] == 0))
|
||||||
parm_count = 0;
|
parm_count = 0;
|
||||||
|
|
||||||
svector<NetExpr*>eparms (parm_count);
|
vector<NetExpr*>eparms (parm_count);
|
||||||
|
|
||||||
perm_string name = peek_tail_name(path_);
|
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_);
|
NetScope*task = des->find_task(scope, path_);
|
||||||
if (task == 0) {
|
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 "
|
cerr << get_fileline() << ": error: Enable of unknown task "
|
||||||
<< "``" << path_ << "''." << endl;
|
<< "``" << path_ << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -3169,6 +3175,39 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||||
return block;
|
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<NetExpr*> 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
|
* Elaborate a procedural continuous assign. This really looks very
|
||||||
* much like other procedural assignments, at this point, but there
|
* much like other procedural assignments, at this point, but there
|
||||||
|
|
|
||||||
|
|
@ -397,13 +397,13 @@ NexusSet* NetRepeat::nex_input(bool rem_out)
|
||||||
*/
|
*/
|
||||||
NexusSet* NetSTask::nex_input(bool rem_out)
|
NexusSet* NetSTask::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
if (parms_.count() == 0)
|
if (parms_.size() == 0)
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
|
|
||||||
NexusSet*result;
|
NexusSet*result;
|
||||||
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
||||||
else result = new NexusSet;
|
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]) {
|
if (parms_[idx]) {
|
||||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
|
|
|
||||||
|
|
@ -2089,7 +2089,7 @@ const NetNet* NetFuncDef::return_sig() const
|
||||||
}
|
}
|
||||||
|
|
||||||
NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
|
NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
|
||||||
const svector<NetExpr*>&pa)
|
const vector<NetExpr*>&pa)
|
||||||
: name_(0), sfunc_as_task_(sfat), parms_(pa)
|
: name_(0), sfunc_as_task_(sfat), parms_(pa)
|
||||||
{
|
{
|
||||||
name_ = lex_strings.add(na);
|
name_ = lex_strings.add(na);
|
||||||
|
|
@ -2098,7 +2098,7 @@ NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
|
||||||
|
|
||||||
NetSTask::~NetSTask()
|
NetSTask::~NetSTask()
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1)
|
||||||
delete parms_[idx];
|
delete parms_[idx];
|
||||||
|
|
||||||
/* The name_ string is perm-allocated in lex_strings. */
|
/* 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
|
unsigned NetSTask::nparms() const
|
||||||
{
|
{
|
||||||
return parms_.count();
|
return parms_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const NetExpr* NetSTask::parm(unsigned idx) const
|
const NetExpr* NetSTask::parm(unsigned idx) const
|
||||||
|
|
|
||||||
|
|
@ -3191,7 +3191,7 @@ class NetSTask : public NetProc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
|
NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
|
||||||
const svector<NetExpr*>&);
|
const std::vector<NetExpr*>&);
|
||||||
~NetSTask();
|
~NetSTask();
|
||||||
|
|
||||||
const char* name() const;
|
const char* name() const;
|
||||||
|
|
@ -3209,7 +3209,7 @@ class NetSTask : public NetProc {
|
||||||
private:
|
private:
|
||||||
const char* name_;
|
const char* name_;
|
||||||
ivl_sfunc_as_task_t sfunc_as_task_;
|
ivl_sfunc_as_task_t sfunc_as_task_;
|
||||||
svector<NetExpr*>parms_;
|
std::vector<NetExpr*>parms_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1646,8 +1646,29 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope)
|
||||||
return rc;
|
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)
|
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.");
|
show_stmt_file_line(net, "System task call.");
|
||||||
|
|
||||||
draw_vpi_task_call(net);
|
draw_vpi_task_call(net);
|
||||||
|
|
|
||||||
|
|
@ -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_DEASSIGN_WR(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_DELAY(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_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_DISABLE(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_DIV(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);
|
extern bool of_DIV_S(vthread_t thr, vvp_code_t code);
|
||||||
|
|
|
||||||
|
|
@ -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} },
|
{ "%deassign/wr",of_DEASSIGN_WR,1,{OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||||
{ "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
{ "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||||
{ "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, 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", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||||
{ "%div/s", of_DIV_S, 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} },
|
{ "%div/wr", of_DIV_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||||
|
|
|
||||||
|
|
@ -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
|
selects an index register, which contains the actual delay. This
|
||||||
supports run-time calculated delays.
|
supports run-time calculated delays.
|
||||||
|
|
||||||
|
* %delete/obj <var-label>
|
||||||
|
|
||||||
|
Arrange for the dynamic object at the target label to be deleted.
|
||||||
|
This has no effect on the object or string stack.
|
||||||
|
|
||||||
* %disable <scope-label>
|
* %disable <scope-label>
|
||||||
|
|
||||||
This instruction terminates threads that are part of a specific
|
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 <idx> is the
|
Create a new array (of int objects) with a size. the <idx> is the
|
||||||
address of an index variable that contains the computed array size to
|
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.
|
NOTE: For now, assume this is an array of int values.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2011,6 +2011,21 @@ bool of_DELAYX(vthread_t thr, vvp_code_t cp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* %delete/obj <label>
|
||||||
|
*
|
||||||
|
* This operator works by assigning a nil to the target object. This
|
||||||
|
* causes any value that might be there to be garbage collected, thus
|
||||||
|
* deleting the object.
|
||||||
|
*/
|
||||||
|
bool of_DELETE_OBJ(vthread_t thr, vvp_code_t cp)
|
||||||
|
{
|
||||||
|
/* set the value into port 0 of the destination. */
|
||||||
|
vvp_net_ptr_t ptr (cp->net, 0);
|
||||||
|
vvp_send_object(ptr, 0, thr->wt_context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool do_disable(vthread_t thr, vthread_t match)
|
static bool do_disable(vthread_t thr, vthread_t match)
|
||||||
{
|
{
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
|
|
|
||||||
|
|
@ -677,6 +677,7 @@ void vvp_fun_signal_object_sa::recv_object(vvp_net_ptr_t ptr, vvp_object_t bit,
|
||||||
assert(ptr.port() == 0);
|
assert(ptr.port() == 0);
|
||||||
|
|
||||||
if (needs_init_ || value_ != bit) {
|
if (needs_init_ || value_ != bit) {
|
||||||
|
if (value_) delete value_;
|
||||||
value_ = bit;
|
value_ = bit;
|
||||||
needs_init_ = false;
|
needs_init_ = false;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue