From 636758f66d649f32b4a77c2c6c37f64a39bd518e Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 21 May 2009 14:41:58 -0700 Subject: [PATCH] Add support for `celldefine, vpiCellInstance This patch adds real functionality for `celldefine and pushes this property to the run time which can access this with vpiCellInstance. This is technically only available for a module, but all scopes have the property and only modules should return true when the 'endmodule' is between a `celldefine and `endcelldefine directive. --- Module.cc | 3 ++- Module.h | 2 ++ design_dump.cc | 1 + elab_scope.cc | 2 ++ ivl.def | 1 + ivl_target.h | 4 ++++ ivlpp/main.c | 24 ++++++++++++++------- lexor.lex | 20 +++++++++++------- net_scope.cc | 1 + netlist.h | 6 +++++- parse.y | 2 +- parse_misc.h | 4 +++- pform.cc | 3 ++- pform.h | 2 +- pform_dump.cc | 6 ++++-- t-dll-api.cc | 6 ++++++ t-dll.cc | 1 + t-dll.h | 2 ++ tgt-stub/stub.c | 3 ++- tgt-vvp/vvp_scope.c | 4 ++-- vpi_user.h | 51 +++++++++++++++++++++++---------------------- vvp/compile.h | 3 ++- vvp/parse.y | 10 ++++----- vvp/vpi_priv.h | 1 + vvp/vpi_scope.cc | 8 ++++++- 25 files changed, 112 insertions(+), 58 deletions(-) diff --git a/Module.cc b/Module.cc index d880c00092..789e4137a0 100644 --- a/Module.cc +++ b/Module.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -29,6 +29,7 @@ Module::Module(perm_string n) : PScope(n) { library_flag = false; + is_cell = false; default_nettype = NetNet::NONE; } diff --git a/Module.h b/Module.h index f5fb524fd6..4f4ead3d54 100644 --- a/Module.h +++ b/Module.h @@ -74,6 +74,8 @@ class Module : public PScope, public LineInfo { other effect. */ bool library_flag; + bool is_cell; + NetNet::Type default_nettype; /* specparams are simpler then other params, in that they have diff --git a/design_dump.cc b/design_dump.cc index cf54cfb0de..30a98325b4 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1081,6 +1081,7 @@ void NetScope::dump(ostream&o) const print_type(o); if (is_auto()) o << " (automatic)"; + if (is_cell()) o << " (cell)"; o << endl; for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) diff --git a/elab_scope.cc b/elab_scope.cc index f9a20cf890..afc4385736 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -479,6 +479,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope, elaborate_scope_events_(des, scope, events); + scope->is_cell(is_cell); + return des->errors == 0; } diff --git a/ivl.def b/ivl.def index d57d9ad0de..c254c422a1 100644 --- a/ivl.def +++ b/ivl.def @@ -161,6 +161,7 @@ ivl_scope_event ivl_scope_events ivl_scope_file ivl_scope_is_auto +ivl_scope_is_cell ivl_scope_lineno ivl_scope_logs ivl_scope_log diff --git a/ivl_target.h b/ivl_target.h index 78723d1554..8a2758a46a 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -1537,6 +1537,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net); * ivl_scope_is_auto * Is the task or function declared to be automatic? * + * ivl_scope_is_cell + * Is the module defined to be a cell? + * * ivl_scope_var * ivl_scope_vars * REMOVED @@ -1614,6 +1617,7 @@ 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_is_cell(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/ivlpp/main.c b/ivlpp/main.c index df9d1b8114..1b3906c550 100644 --- a/ivlpp/main.c +++ b/ivlpp/main.c @@ -214,26 +214,34 @@ int main(int argc, char*argv[]) FILE*precomp_out = NULL; /* Define preprocessor keywords that I plan to just pass. */ + /* From 1364-2005 Chapter 19. */ + define_macro("begin_keywords", "`begin_keywords", 1, 0); define_macro("celldefine", "`celldefine", 1, 0); - define_macro("default_decay_time", "`default_decay_time", 1, 0); define_macro("default_nettype", "`default_nettype", 1, 0); + define_macro("end_keywords", "`end_keywords", 1, 0); + define_macro("endcelldefine", "`endcelldefine", 1, 0); + define_macro("line", "`line", 1, 0); + define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0); + define_macro("pragma", "`pragma", 1, 0); + define_macro("resetall", "`resetall", 1, 0); + define_macro("timescale", "`timescale", 1, 0); + define_macro("unconnected_drive", "`unconnected_drive", 1, 0); + + /* From 1364-2005 Annex D. */ + define_macro("default_decay_time", "`default_decay_time", 1, 0); define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0); define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0); - define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0); define_macro("delay_mode_path", "`delay_mode_path", 1, 0); + define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0); define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0); + + /* From other places. */ define_macro("disable_portfaults", "`disable_portfaults", 1, 0); define_macro("enable_portfaults", "`enable_portfaults", 1, 0); - define_macro("endcelldefine", "`endcelldefine", 1, 0); define_macro("endprotect", "`endprotect", 1, 0); - define_macro("line", "`line", 1, 0); define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0); - define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0); define_macro("protect", "`protect", 1, 0); - define_macro("resetall", "`resetall", 1, 0); define_macro("suppress_faults", "`suppress_faults", 1, 0); - define_macro("timescale", "`timescale", 1, 0); - define_macro("unconnected_drive", "`unconnected_drive", 1, 0); define_macro("uselib", "`uselib", 1, 0); include_cnt = 2; diff --git a/lexor.lex b/lexor.lex index 447eaf8134..6668cf5148 100644 --- a/lexor.lex +++ b/lexor.lex @@ -88,6 +88,7 @@ static list keyword_mask_stack; static int comment_enter; static bool in_module = false; +bool in_celldefine = false; %} %x CCOMMENT @@ -362,28 +363,33 @@ S [afpnumkKMGT] yylloc.first_line += 1; BEGIN(0); } +^{W}?`celldefine{W}?.* { in_celldefine = true; } +^{W}?`endcelldefine{W}?.* { in_celldefine = false; } /* These are directives that I do not yet support. I think that IVL should handle these, not an external preprocessor. */ + /* From 1364-2005 Chapter 19. */ +^{W}?`line{W}?.* { } +^{W}?`nounconnected_drive{W}?.* { } +^{W}?`pragme{W}?.* { } +^{W}?`resetall{W}?.* { } +^{W}?`unconnected_drive{W}?.* { } -^{W}?`celldefine{W}?.* { } + /* From 1364-2005 Annex D. */ ^{W}?`default_decay_time{W}?.* { } ^{W}?`default_trireg_strength{W}?.* { } ^{W}?`delay_mode_distributed{W}?.* { } -^{W}?`delay_mode_unit{W}?.* { } ^{W}?`delay_mode_path{W}?.* { } +^{W}?`delay_mode_unit{W}?.* { } ^{W}?`delay_mode_zero{W}?.* { } + + /* From other places. */ ^{W}?`disable_portfaults{W}?.* { } ^{W}?`enable_portfaults{W}?.* { } -^{W}?`endcelldefine{W}?.* { } `endprotect { } -^{W}?`line{W}?.* { } ^{W}?`nosuppress_faults{W}?.* { } -^{W}?`nounconnected_drive{W}?.* { } `protect { } -^{W}?`resetall{W}?.* { } ^{W}?`suppress_faults{W}?.* { } -^{W}?`unconnected_drive{W}?.* { } ^{W}?`uselib{W}?.* { } ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); } diff --git a/net_scope.cc b/net_scope.cc index 851ab0fb1c..3a2e6f91b9 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -41,6 +41,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t) events_ = 0; lcounter_ = 0; is_auto_ = false; + is_cell_ = false; if (up) { default_nettype_ = up->default_nettype(); diff --git a/netlist.h b/netlist.h index ca9c78fbcc..387adffc81 100644 --- a/netlist.h +++ b/netlist.h @@ -761,6 +761,10 @@ class NetScope : public Attrib { void is_auto(bool is_auto__) { is_auto_ = is_auto__; }; bool is_auto() const { return is_auto_; }; + /* Is the module a cell (is in a `celldefine) */ + void is_cell(bool is_cell__) { is_cell_ = is_cell__; }; + bool is_cell() const { return is_cell_; }; + const NetTaskDef* task_def() const; const NetFuncDef* func_def() const; @@ -908,7 +912,7 @@ class NetScope : public Attrib { NetScope*sub_; unsigned lcounter_; - bool is_auto_; + bool is_auto_, is_cell_; }; /* diff --git a/parse.y b/parse.y index 84a0f2005f..e24d67bbc6 100644 --- a/parse.y +++ b/parse.y @@ -1923,7 +1923,7 @@ module : attribute_list_opt module_start IDENTIFIER { pform_module_set_ports($6); } module_item_list_opt K_endmodule - { pform_endmodule($3); + { pform_endmodule($3, in_celldefine); delete[]$3; } diff --git a/parse_misc.h b/parse_misc.h index d82b3c8f92..6aa623a139 100644 --- a/parse_misc.h +++ b/parse_misc.h @@ -1,7 +1,7 @@ #ifndef __parse_misc_H #define __parse_misc_H /* - * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -65,4 +65,6 @@ extern ostream& operator << (ostream&, const YYLTYPE&loc); extern unsigned error_count, warn_count; extern unsigned long based_size; +extern bool in_celldefine; + #endif diff --git a/pform.cc b/pform.cc index b3bac91035..b87ac6e2b7 100644 --- a/pform.cc +++ b/pform.cc @@ -449,11 +449,12 @@ void pform_module_set_ports(vector*ports) } } -void pform_endmodule(const char*name) +void pform_endmodule(const char*name, bool in_celldefine) { assert(pform_cur_module); perm_string mod_name = pform_cur_module->mod_name(); assert(strcmp(name, mod_name) == 0); + pform_cur_module->is_cell = in_celldefine; map::const_iterator test = pform_modules.find(mod_name); diff --git a/pform.h b/pform.h index ef18234e98..92166d41bf 100644 --- a/pform.h +++ b/pform.h @@ -159,7 +159,7 @@ extern void pform_module_define_port(const struct vlltype&li, extern Module::port_t* pform_module_port_reference(perm_string name, const char*file, unsigned lineno); -extern void pform_endmodule(const char*); +extern void pform_endmodule(const char*, bool in_celldefine); extern void pform_make_udp(perm_string name, list*parms, svector*decl, list*table, diff --git a/pform_dump.cc b/pform_dump.cc index e65a7c7bca..a522eb8ac8 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -1147,7 +1147,9 @@ void Module::dump(ostream&out) const out << " *) "; } - out << "module " << mod_name() << ";" << endl; + out << "module " << mod_name() << ";"; + if (is_cell) out << " // Is in `celldefine."; + out << endl; for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { port_t*cur = ports[idx]; diff --git a/t-dll-api.cc b/t-dll-api.cc index 46e261b93e..e5a513e8df 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -1655,6 +1655,12 @@ extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net) return net->is_auto; } +extern "C" unsigned ivl_scope_is_cell(ivl_scope_t net) +{ + assert(net); + return net->is_cell; +} + extern "C" unsigned ivl_scope_lineno(ivl_scope_t net) { assert(net); diff --git a/t-dll.cc b/t-dll.cc index a66feefb35..f1b18f8572 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2389,6 +2389,7 @@ void dll_target::scope(const NetScope*net) scop->nattr = net->attr_cnt(); scop->attr = fill_in_attributes(net); scop->is_auto = net->is_auto(); + scop->is_cell = net->is_cell(); switch (net->type()) { case NetScope::MODULE: diff --git a/t-dll.h b/t-dll.h index e6c7bd6bc0..5006a6ab48 100644 --- a/t-dll.h +++ b/t-dll.h @@ -606,6 +606,8 @@ struct ivl_scope_s { ivl_statement_t def; unsigned is_auto; + unsigned is_cell; + unsigned ports; ivl_signal_t*port; diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 98723b0a88..2a378b7370 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1533,7 +1533,8 @@ static int show_scope(ivl_scope_t net, void*x) 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)); + fprintf(out, " module %s%s", ivl_scope_tname(net), + ivl_scope_is_cell(net) ? " (cell)" : ""); break; case IVL_SCT_FUNCTION: fprintf(out, " function %s%s", is_auto, ivl_scope_tname(net)); diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index eea3ab47b4..3d6b119ca3 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -1825,9 +1825,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) ivl_scope_lineno(net)); if (parent) { - fprintf(vvp_out, ", %d %d, S_%p;\n", + fprintf(vvp_out, ", %d %d %u, S_%p;\n", ivl_file_table_index(ivl_scope_def_file(net)), - ivl_scope_def_lineno(net), parent); + ivl_scope_def_lineno(net), ivl_scope_is_cell(net), parent); } else { fprintf(vvp_out, ";\n"); diff --git a/vpi_user.h b/vpi_user.h index c335c0a72b..ba019190bf 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -304,33 +304,34 @@ typedef struct t_vpi_delay { #define vpiCallback 1000 /* PROPERTIES */ -#define vpiUndefined (-1) -#define vpiType 1 -#define vpiName 2 -#define vpiFullName 3 -#define vpiSize 4 -#define vpiFile 5 -#define vpiLineNo 6 -#define vpiTopModule 7 -#define vpiDefName 9 +#define vpiUndefined (-1) +#define vpiType 1 +#define vpiName 2 +#define vpiFullName 3 +#define vpiSize 4 +#define vpiFile 5 +#define vpiLineNo 6 +#define vpiTopModule 7 +#define vpiCellInstance 8 +#define vpiDefName 9 #define vpiTimeUnit 11 #define vpiTimePrecision 12 -#define vpiDefFile 15 -#define vpiDefLineNo 16 -#define vpiNetType 22 -# define vpiWire 1 -#define vpiArray 28 -#define vpiEdge 36 -# define vpiNoEdge 0x00 /* No edge */ -# define vpiEdge01 0x01 /* 0 --> 1 */ -# define vpiEdge10 0x02 /* 1 --> 0 */ -# define vpiEdge0x 0x04 /* 0 --> x */ -# define vpiEdgex1 0x08 /* x --> 1 */ -# define vpiEdge1x 0x10 /* 1 --> x */ -# define vpiEdgex0 0x20 /* x --> 0 */ -# define vpiPosedge (vpiEdgex1|vpiEdge01|vpiEdge0x) -# define vpiNegedge (vpiEdgex0|vpiEdge10|vpiEdge1x) -# define vpiAnyEdge (vpiPosedge|vpiNegedge) +#define vpiDefFile 15 +#define vpiDefLineNo 16 +#define vpiNetType 22 +# define vpiWire 1 +#define vpiArray 28 +#define vpiEdge 36 +# define vpiNoEdge 0x00 /* No edge */ +# define vpiEdge01 0x01 /* 0 --> 1 */ +# define vpiEdge10 0x02 /* 1 --> 0 */ +# define vpiEdge0x 0x04 /* 0 --> x */ +# define vpiEdgex1 0x08 /* x --> 1 */ +# define vpiEdge1x 0x10 /* 1 --> x */ +# define vpiEdgex0 0x20 /* x --> 0 */ +# define vpiPosedge (vpiEdgex1|vpiEdge01|vpiEdge0x) +# define vpiNegedge (vpiEdgex0|vpiEdge10|vpiEdge1x) +# define vpiAnyEdge (vpiPosedge|vpiNegedge) #define vpiConstType 40 # define vpiDecConst 1 # define vpiRealConst 2 diff --git a/vvp/compile.h b/vvp/compile.h index c280367554..f637322468 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -414,7 +414,8 @@ extern void compile_codelabel(char*label); */ extern void compile_scope_decl(char*typ, char*lab, char*nam, char*tnam, char*par, long file_idx, long lineno, - long def_file_idx, long def_lineno); + long def_file_idx, long def_lineno, + long is_cell); extern void compile_scope_recall(char*sym); /* diff --git a/vvp/parse.y b/vvp/parse.y index ae2454891e..03cf2dccf1 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -574,19 +574,19 @@ statement parent scope, then this is a root scope. */ | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING T_STRING T_NUMBER T_NUMBER ';' - { compile_scope_decl($1, $3, $5, $6, 0, $7, $8, $7, $8); } + { compile_scope_decl($1, $3, $5, $6, 0, $7, $8, $7, $8, 0); } | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING T_STRING T_NUMBER T_NUMBER ',' - T_NUMBER T_NUMBER ',' T_SYMBOL ';' - { compile_scope_decl($1, $3, $5, $6, $13, $7, $8, $10, $11); } + T_NUMBER T_NUMBER T_NUMBER ',' T_SYMBOL ';' + { compile_scope_decl($1, $3, $5, $6, $14, $7, $8, $10, $11, $12); } /* XXXX Legacy declaration has no type name. */ | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING ';' - { compile_scope_decl($1, $3, $5, 0, 0, 0, 0, 0, 0); } + { compile_scope_decl($1, $3, $5, 0, 0, 0, 0, 0, 0, 0); } | T_LABEL K_SCOPE T_SYMBOL ',' T_STRING ',' T_SYMBOL ';' - { compile_scope_decl($1, $3, $5, 0, $7, 0, 0, 0, 0); } + { compile_scope_decl($1, $3, $5, 0, $7, 0, 0, 0, 0, 0); } /* Scope recall has no label of its own, but refers by label to a declared scope. */ diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index a3a40653a7..a1d0ba6e8b 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -186,6 +186,7 @@ struct __vpiScope { unsigned def_file_idx; unsigned def_lineno; bool is_automatic; + bool is_cell; /* The scope has a system time of its own. */ struct __vpiSystemTime scoped_time; struct __vpiSystemTime scoped_stime; diff --git a/vvp/vpi_scope.cc b/vvp/vpi_scope.cc index 975928bfe1..ac3aac5a5f 100644 --- a/vvp/vpi_scope.cc +++ b/vvp/vpi_scope.cc @@ -128,6 +128,9 @@ static int scope_get(int code, vpiHandle obj) assert(handle_is_scope(obj)); switch (code) { + case vpiCellInstance: + return (int) ref->is_cell; + case vpiDefLineNo: return ref->def_lineno; @@ -395,7 +398,7 @@ static void attach_to_scope_(struct __vpiScope*scope, vpiHandle obj) void compile_scope_decl(char*label, char*type, char*name, char*tname, char*parent, long file_idx, long lineno, - long def_file_idx, long def_lineno) + long def_file_idx, long def_lineno, long is_cell) { struct __vpiScope*scope = new struct __vpiScope; count_vpi_scopes += 1; @@ -409,6 +412,9 @@ compile_scope_decl(char*label, char*type, char*name, char*tname, base_type = &type[0]; } + if (is_cell) scope->is_cell = true; + else scope->is_cell = false; + if (strcmp(base_type,"module") == 0) { scope->base.vpi_type = &vpip_scope_module_rt; } else if (strcmp(base_type,"function") == 0) {