From 0833d9e37ae647a150d69fb3a0e5678cbd6af463 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 30 Apr 2012 21:12:59 -0700 Subject: [PATCH] Basic support for program blocks. --- Module.cc | 1 + Module.h | 5 +++++ parse.y | 5 +---- pform.cc | 9 +++++---- pform.h | 8 ++++++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Module.cc b/Module.cc index 66efe26b04..589e3e7e31 100644 --- a/Module.cc +++ b/Module.cc @@ -32,6 +32,7 @@ Module::Module(perm_string n) { library_flag = false; is_cell = false; + program_block = false; uc_drive = UCD_NONE; timescale_warn_done = false; time_unit = 0; diff --git a/Module.h b/Module.h index 1f9c32349a..29da46ae18 100644 --- a/Module.h +++ b/Module.h @@ -76,6 +76,11 @@ class Module : public PScopeExtra, public LineInfo { bool is_cell; + /* This is true if the module represents a program block + instead of a module/cell. Program blocks have content + restrictions and slightly modify scheduling semantics. */ + bool program_block; + enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; UCDriveType uc_drive; diff --git a/parse.y b/parse.y index cc5fe859ec..56443e206b 100644 --- a/parse.y +++ b/parse.y @@ -3754,7 +3754,7 @@ local_timeunit_prec_decl module : attribute_list_opt module_start IDENTIFIER - { pform_startmodule($3, @2.text, @2.first_line, $1); } + { pform_startmodule(@2, $3, $2==K_program, $1); } module_parameter_port_list_opt module_port_list_opt module_attribute_foreign ';' @@ -3796,9 +3796,6 @@ module break; } } - if ($2 == K_program) { - yyerror(@2, "sorry: Program blocks not supported yet."); - } pform_endmodule($3, in_celldefine, ucd); delete[]$3; have_timeunit_decl = false; // We will allow decls again. diff --git a/pform.cc b/pform.cc index aa51b44686..4ff15138cc 100644 --- a/pform.cc +++ b/pform.cc @@ -796,13 +796,14 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val, return res; } -void pform_startmodule(const char*name, const char*file, unsigned lineno, - list*attr) +void pform_startmodule(const struct vlltype&loc, const char*name, + bool program_block, list*attr) { assert( pform_cur_module == 0 ); perm_string lex_name = lex_strings.make(name); pform_cur_module = new Module(lex_name); + pform_cur_module->program_block = program_block; /* Set the local time unit/precision to the global value. */ pform_cur_module->time_unit = pform_time_unit; pform_cur_module->time_precision = pform_time_prec; @@ -813,7 +814,7 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno, * a timescale directive. */ pform_cur_module->time_from_timescale = pform_timescale_file != 0; - FILE_NAME(pform_cur_module, file, lineno); + FILE_NAME(pform_cur_module, loc); pform_cur_module->library_flag = pform_library_flag; ivl_assert(*pform_cur_module, lexical_scope == 0); @@ -824,7 +825,7 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno, scope_generate_counter = 1; if (warn_timescale && pform_timescale_file - && (strcmp(pform_timescale_file,file) != 0)) { + && (strcmp(pform_timescale_file,loc.text) != 0)) { cerr << pform_cur_module->get_fileline() << ": warning: " << "timescale for " << name diff --git a/pform.h b/pform.h index 838fad779b..d1a5d8df50 100644 --- a/pform.h +++ b/pform.h @@ -145,9 +145,13 @@ extern PWire* pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_ty * module has been noticed in the source file and the following events * are to apply to the scope of that module. The endmodule causes the * pform to close up and finish the named module. + * + * The program_flag indicates that the module is actually a program + * block. This has implications during parse and during + * elaboration/code generation. */ -extern void pform_startmodule(const char*, const char*file, unsigned lineno, - list*attr); +extern void pform_startmodule(const struct vlltype&loc, const char*name, + bool program_block, list*attr); extern void pform_check_timeunit_prec(); extern void pform_module_set_ports(vector*);