Push the automatic property for tasks and functions to the code gen.

This patch pushes the automatic property for both tasks and
functions to the code generators. The vvp back end does not
currently support this so it will error out during code
generation. The VHDL back end should be able to use this
property and tgt-stub prints the property. Having this will
also make it easier when we do adding this to the runtime.
This commit is contained in:
Cary R 2008-08-19 18:39:49 -07:00 committed by Stephen Williams
parent 5e512e6570
commit 11109f519c
18 changed files with 67 additions and 54 deletions

View File

@ -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;
}

View File

@ -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.
*
*/

10
PTask.h
View File

@ -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<PWire *>*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<PWire*>*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<PWire *>*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<PWire *> *ports_;
Statement *statement_;
bool is_auto_;
};
#endif

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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_;
};
/*

18
parse.y
View File

@ -239,7 +239,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
%type <flag> from_exclude
%type <number> number
%type <flag> signed_opt udp_reg_opt edge_operator
%type <flag> signed_opt udp_reg_opt edge_operator automatic_opt
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
%type <letter> udp_input_sym udp_output_sym
%type <text> 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); }

View File

@ -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;
}

View File

@ -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);

View File

@ -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) << "";

View File

@ -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);

View File

@ -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_)
@ -2320,6 +2321,7 @@ void dll_target::scope(const NetScope*net)
scope->time_units = net->time_unit();
scope->nattr = net->attr_cnt();
scope->attr = fill_in_attributes(net);
scope->is_auto = net->is_auto();
switch (net->type()) {
case NetScope::MODULE:

View File

@ -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;

View File

@ -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),

View File

@ -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;