From 94acc39b55399c1b54e799585fe377279451fe51 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 31 Oct 2010 14:07:38 -0700 Subject: [PATCH] Detect the net.name() method and generate a system function. SystemVerilog .name() methods can be converted to equivilent system functions. --- compiler.h | 7 +++++++ elab_expr.cc | 37 ++++++++++++++++++++++++++++++++++++- ivl_target.h | 1 + tgt-stub/stub.c | 3 +++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/compiler.h b/compiler.h index 1cd14d360..4a2b84bd5 100644 --- a/compiler.h +++ b/compiler.h @@ -161,6 +161,13 @@ static inline bool gn_var_can_be_uwire(void) return false; } +static inline bool gn_system_verilog(void) +{ + if (generation_flag == GN_VER2009) + return true; + return false; +} + /* The bits of these GN_KEYWORDS_* constants define non-intersecting sets of keywords. The compiler enables groups of keywords by setting lexor_keyword_mask with the OR of the bits for the keywords to be diff --git a/elab_expr.cc b/elab_expr.cc index bb0f97392..97294217b 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2200,6 +2200,41 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, } } + // Maybe this is a method attached to an enumeration name? If + // this is system verilog, then test to see if the name is + // really a method attached to an object. + + if (gn_system_verilog() && found_in==0 && path_.size() >= 2) { + pform_name_t use_path = path_; + perm_string method_name = peek_tail_name(use_path); + use_path.pop_back(); + + found_in = symbol_search(this, des, scope, use_path, + net, par, eve, ex1, ex2); + + if (net != 0) { + const char*func_name = 0; + if (method_name == "name") { + func_name = "$ivl_method$name"; + } else { + cerr << get_fileline() << ": error: " + << "Unknown method name `" << method_name << "'" + << " attached to " << use_path << "." << endl; + des->errors += 1; + return elaborate_expr_net(des, scope, net, found_in, false); + } + + NetESFunc*tmp = new NetESFunc(func_name, IVL_VT_STRING, 0, 1); + tmp->parm(0, elaborate_expr_net(des, scope, net, found_in, false)); + tmp->set_line(*this); + + if (debug_elaborate) + cerr << get_fileline() << ": debug: Generate " + << func_name << "(" << use_path << ")" << endl; + return tmp; + } + } + // At this point we've exhausted all the possibilities that // are not scopes. If this is not a system task argument, then // it cannot be a scope name, so give up. @@ -2207,7 +2242,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, if (! sys_task_arg) { // I cannot interpret this identifier. Error message. cerr << get_fileline() << ": error: Unable to bind wire/reg/memory " - "`" << path_ << "' in `" << scope_path(scope) << "'" << endl; + "`" << path_ << "' in `" << scope_path(scope) << "'"<< endl; des->errors += 1; return 0; } diff --git a/ivl_target.h b/ivl_target.h index f5c9ea421..e4b002883 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -405,6 +405,7 @@ typedef enum ivl_variable_type_e { IVL_VT_REAL = 2, IVL_VT_BOOL = 3, IVL_VT_LOGIC = 4, + IVL_VT_STRING = 5, IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */ } ivl_variable_type_t; diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index f6a325116..5de27490d 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -166,6 +166,9 @@ const char*data_type_string(ivl_variable_type_t vtype) case IVL_VT_LOGIC: vt = "logic"; break; + case IVL_VT_STRING: + vt = "string"; + break; } return vt;