diff --git a/PFunction.cc b/PFunction.cc index fb26c434b..1a3146a8a 100644 --- a/PFunction.cc +++ b/PFunction.cc @@ -21,9 +21,10 @@ #include "PTask.h" -PFunction::PFunction(perm_string name, PScope*parent) +PFunction::PFunction(perm_string name, PScope*parent, bool is_auto) : PScope(name, parent), ports_(0), statement_(0) { + is_auto_ = is_auto; return_type_.type = PTF_NONE; } diff --git a/PTask.cc b/PTask.cc index b829e03f2..3719c4b3c 100644 --- a/PTask.cc +++ b/PTask.cc @@ -21,9 +21,10 @@ # include "PTask.h" -PTask::PTask(perm_string name, PScope*parent) +PTask::PTask(perm_string name, PScope*parent, bool is_auto) : PScope(name, parent), ports_(0), statement_(0) { + is_auto_ = is_auto; } PTask::~PTask() @@ -41,31 +42,3 @@ void PTask::set_statement(Statement*s) assert(statement_ == 0); statement_ = s; } - - -/* - * $Log: PTask.cc,v $ - * Revision 1.7 2002/08/12 01:34:58 steve - * conditional ident string using autoconfig. - * - * Revision 1.6 2001/07/25 03:10:48 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.5 2001/04/19 03:04:47 steve - * Spurious assert of empty statemnt. - * - * Revision 1.4 2001/01/13 22:20:08 steve - * Parse parameters within nested scopes. - * - * Revision 1.3 2000/02/23 02:56:53 steve - * Macintosh compilers do not support ident. - * - * Revision 1.2 1999/07/24 02:11:19 steve - * Elaborate task input ports. - * - * Revision 1.1 1999/07/03 02:12:51 steve - * Elaborate user defined tasks. - * - */ - diff --git a/PTask.h b/PTask.h index 4d9c24e9c..de05ac053 100644 --- a/PTask.h +++ b/PTask.h @@ -51,7 +51,7 @@ struct PTaskFuncArg { class PTask : public PScope, public LineInfo { public: - explicit PTask(perm_string name, PScope*parent); + explicit PTask(perm_string name, PScope*parent, bool is_auto); ~PTask(); void set_ports(svector*p); @@ -69,11 +69,14 @@ class PTask : public PScope, public LineInfo { // Elaborate the statement to finish off the task definition. void elaborate(Design*des, NetScope*scope) const; + bool is_auto() const { return is_auto_; }; + void dump(ostream&, unsigned) const; private: svector*ports_; Statement*statement_; + bool is_auto_; private: // Not implemented PTask(const PTask&); @@ -90,7 +93,7 @@ class PTask : public PScope, public LineInfo { class PFunction : public PScope, public LineInfo { public: - explicit PFunction(perm_string name, PScope*parent); + explicit PFunction(perm_string name, PScope*parent, bool is_auto); ~PFunction(); void set_ports(svector*p); @@ -105,12 +108,15 @@ class PFunction : public PScope, public LineInfo { /* Elaborate the behavioral statement. */ void elaborate(Design *des, NetScope*) const; + bool is_auto() const { return is_auto_; }; + void dump(ostream&, unsigned) const; private: PTaskFuncArg return_type_; svector *ports_; Statement *statement_; + bool is_auto_; }; #endif diff --git a/design_dump.cc b/design_dump.cc index ca8e71d8e..1af627745 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -998,6 +998,7 @@ void NetScope::dump(ostream&o) const o << " generate block"; break; } + if (is_auto()) o << " (automatic)"; o << endl; for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) diff --git a/elab_scope.cc b/elab_scope.cc index b77292dea..5df05b7bc 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -150,6 +150,7 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope, } NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK); + task_scope->is_auto((*cur).second->is_auto()); task_scope->set_line((*cur).second); if (debug_scopes) @@ -179,6 +180,7 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope, } NetScope*func_scope = new NetScope(scope, use_name, NetScope::FUNC); + func_scope->is_auto((*cur).second->is_auto()); func_scope->set_line((*cur).second); if (debug_scopes) diff --git a/ivl.def b/ivl.def index dfcf064cf..22260e7e9 100644 --- a/ivl.def +++ b/ivl.def @@ -143,6 +143,7 @@ ivl_scope_def_lineno ivl_scope_event ivl_scope_events ivl_scope_file +ivl_scope_is_auto ivl_scope_lineno ivl_scope_logs ivl_scope_log diff --git a/ivl_target.h b/ivl_target.h index 7535bd0d4..f04d90f8a 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -1447,6 +1447,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net); * ivl_scope_lineno * Returns the instantiation file and line for this scope. * + * ivl_scope_is_auto + * Is the task or function declared to be automatic? + * * ivl_scope_var * ivl_scope_vars * REMOVED @@ -1523,6 +1526,7 @@ extern unsigned ivl_scope_def_lineno(ivl_scope_t net); extern unsigned ivl_scope_events(ivl_scope_t net); extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx); extern const char* ivl_scope_file(ivl_scope_t net); +extern unsigned ivl_scope_is_auto(ivl_scope_t net); extern unsigned ivl_scope_lineno(ivl_scope_t net); extern unsigned ivl_scope_logs(ivl_scope_t net); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx); diff --git a/net_scope.cc b/net_scope.cc index 2b8baf0cb..d39152cdc 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -41,6 +41,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t) signals_ = 0; events_ = 0; lcounter_ = 0; + is_auto_ = false; if (up) { default_nettype_ = up->default_nettype(); @@ -261,6 +262,7 @@ NetFuncDef* NetScope::func_def() assert( type_ == FUNC ); return func_; } + bool NetScope::in_func() { return (type_ == FUNC) ? true : false; diff --git a/netlist.h b/netlist.h index 05f151d10..141c3d909 100644 --- a/netlist.h +++ b/netlist.h @@ -692,6 +692,9 @@ class NetScope : public Attrib { unsigned get_def_lineno() const { return def_lineno_; }; bool in_func(); + /* Is the task or function automatic. */ + void is_auto(bool is_auto) { is_auto_ = is_auto; }; + bool is_auto() const { return is_auto_; }; const NetTaskDef* task_def() const; const NetFuncDef* func_def() const; @@ -835,6 +838,7 @@ class NetScope : public Attrib { NetScope*sub_; unsigned lcounter_; + bool is_auto_; }; /* diff --git a/parse.y b/parse.y index 8f180090d..4b2dae490 100644 --- a/parse.y +++ b/parse.y @@ -239,7 +239,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %type from_exclude %type number -%type signed_opt udp_reg_opt edge_operator +%type signed_opt udp_reg_opt edge_operator automatic_opt %type drive_strength drive_strength_opt dr_strength0 dr_strength1 %type udp_input_sym udp_output_sym %type udp_input_list udp_sequ_entry udp_comb_entry @@ -2096,7 +2096,7 @@ module_item | K_task automatic_opt IDENTIFIER ';' { assert(current_task == 0); - current_task = pform_push_task_scope($3); + current_task = pform_push_task_scope($3, $2); FILE_NAME(current_task, @1); } task_item_list_opt @@ -2111,7 +2111,7 @@ module_item | K_task automatic_opt IDENTIFIER { assert(current_task == 0); - current_task = pform_push_task_scope($3); + current_task = pform_push_task_scope($3, $2); FILE_NAME(current_task, @1); } '(' task_port_decl_list ')' ';' @@ -2138,7 +2138,7 @@ module_item | K_function automatic_opt function_range_or_type_opt IDENTIFIER ';' { assert(current_function == 0); - current_function = pform_push_function_scope($4); + current_function = pform_push_function_scope($4, $2); FILE_NAME(current_function, @1); } function_item_list statement @@ -2153,7 +2153,7 @@ module_item | K_function automatic_opt function_range_or_type_opt IDENTIFIER { assert(current_function == 0); - current_function = pform_push_function_scope($4); + current_function = pform_push_function_scope($4, $2); FILE_NAME(current_function, @1); } '(' task_port_decl_list ')' ';' @@ -2279,12 +2279,8 @@ module_item ; automatic_opt - : K_automatic - { yyerror(@1, "sorry: automatic tasks/functions are not " - "currently supported."); - yyerrok; - } - | {} + : K_automatic { $$ = true; } + | { $$ = false;} ; generate_if : K_if '(' expression ')' { pform_start_generate_if(@1, $3); } diff --git a/pform.cc b/pform.cc index 6b3612a06..7057376cc 100644 --- a/pform.cc +++ b/pform.cc @@ -103,17 +103,18 @@ void pform_pop_scope() } } -PTask* pform_push_task_scope(char*name) +PTask* pform_push_task_scope(char*name, bool is_auto) { perm_string task_name = lex_strings.make(name); PTask*task; if (pform_cur_generate) { - task = new PTask(task_name, pform_cur_generate->lexical_scope); + task = new PTask(task_name, pform_cur_generate->lexical_scope, + is_auto); pform_cur_generate->tasks[task->pscope_name()] = task; pform_cur_generate->lexical_scope = task; } else { - task = new PTask(task_name, lexical_scope); + task = new PTask(task_name, lexical_scope, is_auto); pform_cur_module->tasks[task->pscope_name()] = task; lexical_scope = task; } @@ -121,17 +122,18 @@ PTask* pform_push_task_scope(char*name) return task; } -PFunction* pform_push_function_scope(char*name) +PFunction* pform_push_function_scope(char*name, bool is_auto) { perm_string func_name = lex_strings.make(name); PFunction*func; if (pform_cur_generate) { - func = new PFunction(func_name, pform_cur_generate->lexical_scope); + func = new PFunction(func_name, pform_cur_generate->lexical_scope, + is_auto); pform_cur_generate->funcs[func->pscope_name()] = func; pform_cur_generate->lexical_scope = func; } else { - func = new PFunction(func_name, lexical_scope); + func = new PFunction(func_name, lexical_scope, is_auto); pform_cur_module->funcs[func->pscope_name()] = func; lexical_scope = func; } diff --git a/pform.h b/pform.h index a94be9f96..ae410c8e7 100644 --- a/pform.h +++ b/pform.h @@ -175,8 +175,8 @@ extern void pform_make_udp(perm_string name, */ extern void pform_pop_scope(); -extern PTask*pform_push_task_scope(char*name); -extern PFunction*pform_push_function_scope(char*name); +extern PTask*pform_push_task_scope(char*name, bool is_auto); +extern PFunction*pform_push_function_scope(char*name, bool is_auto); extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt); diff --git a/pform_dump.cc b/pform_dump.cc index ba6e60912..f506bd655 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -715,6 +715,7 @@ void PForStatement::dump(ostream&out, unsigned ind) const void PFunction::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "function "; + if (is_auto_) cout << "automatic "; switch (return_type_.type) { case PTF_NONE: out << "?none? "; @@ -775,6 +776,9 @@ void PRepeat::dump(ostream&out, unsigned ind) const void PTask::dump(ostream&out, unsigned ind) const { + out << setw(ind) << "" << "task "; + if (is_auto_) cout << "automatic "; + out << pscope_name() << ";" << endl; if (ports_) for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) { out << setw(ind) << ""; diff --git a/t-dll-api.cc b/t-dll-api.cc index e9db3bf5e..379053b45 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -1547,6 +1547,12 @@ extern "C" const char*ivl_scope_file(ivl_scope_t net) return net->file.str(); } +extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net) +{ + assert(net); + return net->is_auto; +} + extern "C" unsigned ivl_scope_lineno(ivl_scope_t net) { assert(net); diff --git a/t-dll.cc b/t-dll.cc index e11692145..98ade6c15 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -575,6 +575,7 @@ void dll_target::add_root(ivl_design_s &des_, const NetScope *s) root_->time_units = s->time_unit(); root_->nattr = s->attr_cnt(); root_->attr = fill_in_attributes(s); + root_->is_auto = 0; des_.nroots_++; if (des_.roots_) @@ -2319,7 +2320,8 @@ void dll_target::scope(const NetScope*net) scope->time_precision = net->time_precision(); scope->time_units = net->time_unit(); scope->nattr = net->attr_cnt(); - scope->attr = fill_in_attributes(net); + scope->attr = fill_in_attributes(net); + scope->is_auto = net->is_auto(); switch (net->type()) { case NetScope::MODULE: diff --git a/t-dll.h b/t-dll.h index c409a6ce9..f5d6fd4b7 100644 --- a/t-dll.h +++ b/t-dll.h @@ -590,6 +590,7 @@ struct ivl_scope_s { /* Scopes that are tasks/functions have a definition. */ ivl_statement_t def; + unsigned is_auto; unsigned ports; ivl_signal_t*port; diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 927312765..aba418c14 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1448,12 +1448,13 @@ static int show_scope(ivl_scope_t net, void*x) ivl_scope_name(net), ivl_scope_params(net), ivl_scope_sigs(net), ivl_scope_logs(net)); + char *is_auto = ivl_scope_is_auto(net) ? "automatic " : ""; switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: fprintf(out, " module %s", ivl_scope_tname(net)); break; case IVL_SCT_FUNCTION: - fprintf(out, " function %s", ivl_scope_tname(net)); + fprintf(out, " function %s%s", is_auto, ivl_scope_tname(net)); break; case IVL_SCT_BEGIN: fprintf(out, " begin : %s", ivl_scope_tname(net)); @@ -1462,7 +1463,7 @@ static int show_scope(ivl_scope_t net, void*x) fprintf(out, " fork : %s", ivl_scope_tname(net)); break; case IVL_SCT_TASK: - fprintf(out, " task %s", ivl_scope_tname(net)); + fprintf(out, " task %s%s", is_auto, ivl_scope_tname(net)); break; default: fprintf(out, " type(%u) %s", ivl_scope_type(net), diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 42f378711..433263b24 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -1769,6 +1769,13 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) { unsigned idx; const char *type; + /* For now we do not support automatic tasks or functions. */ + if (ivl_scope_is_auto(net)) { + fprintf(stderr, "%s:%u: vvp-tgt sorry: automatic tasks/functions " + "are not supported!\n", + ivl_scope_def_file(net), ivl_scope_def_lineno(net)); + exit(1); + } switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: type = "module"; break; case IVL_SCT_FUNCTION: type = "function"; break;