From f95593716fe608f15ee675012b866a2071b39ece Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 12 Jan 2010 20:11:01 +0000 Subject: [PATCH] Fix for pr2924354. Creation of implicit nets requires knowledge of whether an identifier has been declared before it is used. Currently implicit nets are created during elaboration, but by this stage the order of declaration and use is not known. This patch moves the creation of implicit nets into the parser stage. --- Module.cc | 4 +- Module.h | 10 +--- PExpr.cc | 82 +++++++++++++++++++++++++++++++- PExpr.h | 38 +++++++++------ PScope.h | 5 ++ compiler.h | 3 +- elab_expr.cc | 16 ------- elab_net.cc | 25 +--------- elab_scope.cc | 3 +- elab_sig.cc | 126 ++------------------------------------------------ elaborate.cc | 12 +---- main.cc | 4 +- net_scope.cc | 14 +----- netlist.h | 6 +-- pform.cc | 29 ++++++++++-- 15 files changed, 146 insertions(+), 231 deletions(-) diff --git a/Module.cc b/Module.cc index 6fa6fcdf91..690d0cbf5c 100644 --- a/Module.cc +++ b/Module.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 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 @@ -33,7 +33,6 @@ Module::Module(perm_string n) library_flag = false; is_cell = false; uc_drive = UCD_NONE; - default_nettype = NetNet::NONE; timescale_warn_done = false; } @@ -105,4 +104,3 @@ const list& Module::get_gates() const { return gates_; } - diff --git a/Module.h b/Module.h index b9f179d174..e34d45a030 100644 --- a/Module.h +++ b/Module.h @@ -1,7 +1,7 @@ #ifndef __Module_H #define __Module_H /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 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 @@ -79,8 +79,6 @@ class Module : public PScope, public LineInfo { enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; UCDriveType uc_drive; - NetNet::Type default_nettype; - /* specparams are simpler then other params, in that they have no type information. They are merely constant expressions. */ @@ -118,11 +116,7 @@ class Module : public PScope, public LineInfo { map tasks; map funcs; - /* The module has a list of genvars that may be used in - various generate schemes. */ - map genvars; - - /* the module has a list of generate schemes that appear in + /* The module has a list of generate schemes that appear in the module definition. These are used at elaboration time. */ list generate_schemes; diff --git a/PExpr.cc b/PExpr.cc index f375515b27..36dbce9a12 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Stephen Williams + * Copyright (c) 1998-2008,2010 Stephen Williams * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -23,6 +23,7 @@ # include "compiler.h" # include "PExpr.h" +# include "PWire.h" # include "Module.h" # include "netmisc.h" # include @@ -36,6 +37,10 @@ PExpr::~PExpr() { } +void PExpr::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ +} + bool PExpr::has_aa_term(Design*, NetScope*) const { return false; @@ -70,6 +75,13 @@ PEBinary::~PEBinary() { } +void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + assert(left_ && right_); + left_->declare_implicit_nets(scope, type); + right_->declare_implicit_nets(scope, type); +} + bool PEBinary::has_aa_term(Design*des, NetScope*scope) const { assert(left_ && right_); @@ -160,6 +172,13 @@ PECallFunction::~PECallFunction() { } +void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { + parms_[idx]->declare_implicit_nets(scope, type); + } +} + bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const { bool flag = false; @@ -179,6 +198,13 @@ PEConcat::~PEConcat() delete repeat_; } +void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { + parms_[idx]->declare_implicit_nets(scope, type); + } +} + bool PEConcat::has_aa_term(Design*des, NetScope*scope) const { bool flag = false; @@ -245,6 +271,46 @@ PEIdent::~PEIdent() { } +void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + /* We create an implicit wire if this is a simple identifier and + if an identifier of that name has not already been declared in + any enclosing scope. */ + if ((path_.size() == 1) && (path_.front().index.size() == 0)) { + perm_string name = path_.front().name; + LexicalScope*ss = scope; + while (ss) { + if (ss->wires.find(name) != ss->wires.end()) + return; + if (ss->localparams.find(name) != ss->localparams.end()) + return; + if (ss->parameters.find(name) != ss->parameters.end()) + return; + if (ss->genvars.find(name) != ss->genvars.end()) + return; + if (ss->events.find(name) != ss->events.end()) + return; + /* Strictly speaking, we should also check for name clashes + with tasks, functions, named blocks, module instances, + and generate blocks. However, this information is not + readily available. As these names would not be legal in + this context, we can declare implicit nets here and rely + on later checks for name clashes to report the error. */ + + ss = ss->parent_scope(); + } + PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC); + net->set_file(get_file()); + net->set_lineno(get_lineno()); + net->set_range(0, 0, SR_NET, true); + scope->wires[name] = net; + if (warn_implicit) { + cerr << get_fileline() << ": warning: implicit " + "definition of wire '" << name << "'." << endl; + } + } +} + bool PEIdent::has_aa_term(Design*des, NetScope*scope) const { NetNet* net = 0; @@ -310,6 +376,14 @@ PETernary::~PETernary() { } +void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + assert(expr_ && tru_ && fal_); + expr_->declare_implicit_nets(scope, type); + tru_->declare_implicit_nets(scope, type); + fal_->declare_implicit_nets(scope, type); +} + bool PETernary::has_aa_term(Design*des, NetScope*scope) const { assert(expr_ && tru_ && fal_); @@ -327,6 +401,12 @@ PEUnary::~PEUnary() { } +void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) +{ + assert(expr_); + expr_->declare_implicit_nets(scope, type); +} + bool PEUnary::has_aa_term(Design*des, NetScope*scope) const { assert(expr_); diff --git a/PExpr.h b/PExpr.h index e0ae7f58a9..1355b67d0a 100644 --- a/PExpr.h +++ b/PExpr.h @@ -29,6 +29,7 @@ class Design; class Module; +class LexicalScope; class NetNet; class NetExpr; class NetScope; @@ -47,6 +48,16 @@ class PExpr : public LineInfo { virtual void dump(ostream&) const; + // This method tests whether the expression contains any identifiers + // that have not been previously declared in the specified scope or + // in any containing scope. Any such identifiers are added to the + // specified scope as scalar nets of the specified type. + // + // This operation must be performed by the parser, to ensure that + // subsequent declarations do not affect the decision to create an + // implicit net. + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + // This method tests whether the expression contains any // references to automatically allocated variables. virtual bool has_aa_term(Design*des, NetScope*scope) const; @@ -85,10 +96,6 @@ class PExpr : public LineInfo { ivl_variable_type_t expr_type() const { return expr_type_; } unsigned expr_width() const { return expr_width_; } - // During the elaborate_sig phase, we may need to scan - // expressions to find implicit net declarations. - virtual bool elaborate_sig(Design*des, NetScope*scope) const; - // Procedural elaboration of the expression. The expr_width is // the width of the context of the expression (i.e. the // l-value width of an assignment), @@ -159,6 +166,8 @@ class PEConcat : public PExpr { virtual verinum* eval_const(Design*des, NetScope*sc) const; virtual void dump(ostream&) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, @@ -166,7 +175,6 @@ class PEConcat : public PExpr { ivl_variable_type_t&expr_type, bool&unsized_flag); - virtual bool elaborate_sig(Design*des, NetScope*scope) const; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, @@ -257,6 +265,8 @@ class PEIdent : public PExpr { virtual void dump(ostream&) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, @@ -264,8 +274,6 @@ class PEIdent : public PExpr { ivl_variable_type_t&expr_type, bool&unsized_flag); - virtual bool elaborate_sig(Design*des, NetScope*scope) const; - // Identifiers are allowed (with restrictions) is assign l-values. virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; @@ -376,8 +384,6 @@ class PEIdent : public PExpr { NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const; - NetNet*make_implicit_net_(Design*des, NetScope*scope) const; - bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig, long&midx, long&lidx) const; }; @@ -449,6 +455,8 @@ class PEUnary : public PExpr { virtual void dump(ostream&out) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, @@ -456,8 +464,6 @@ class PEUnary : public PExpr { ivl_variable_type_t&expr_type, bool&unsized_flag); - virtual bool elaborate_sig(Design*des, NetScope*scope) const; - virtual NetExpr*elaborate_expr(Design*des, NetScope*, int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; @@ -479,6 +485,8 @@ class PEBinary : public PExpr { virtual void dump(ostream&out) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, @@ -486,8 +494,6 @@ class PEBinary : public PExpr { ivl_variable_type_t&expr_type, bool&unsized_flag); - virtual bool elaborate_sig(Design*des, NetScope*scope) const; - virtual NetExpr*elaborate_expr(Design*des, NetScope*, int expr_width, bool sys_task_arg) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; @@ -613,6 +619,8 @@ class PETernary : public PExpr { virtual void dump(ostream&out) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, @@ -620,8 +628,6 @@ class PETernary : public PExpr { ivl_variable_type_t&expr_type, bool&unsized_flag); - virtual bool elaborate_sig(Design*des, NetScope*scope) const; - virtual NetExpr*elaborate_expr(Design*des, NetScope*, int expr_width, bool sys_task_arg) const; virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const; @@ -657,6 +663,8 @@ class PECallFunction : public PExpr { virtual void dump(ostream &) const; + virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); + virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, diff --git a/PScope.h b/PScope.h index b5f94e4edf..e04fe54e36 100644 --- a/PScope.h +++ b/PScope.h @@ -90,6 +90,11 @@ class LexicalScope { mapwires; PWire* wires_find(perm_string name); + // Genvars in the scope. These will only be present in module + // scopes, but are listed here to allow them to be found when + // creating implicit nets. + map genvars; + // Behaviors (processes) in this scope list behaviors; list analog_behaviors; diff --git a/compiler.h b/compiler.h index 747e411cc9..d3e6b4c89e 100644 --- a/compiler.h +++ b/compiler.h @@ -1,7 +1,7 @@ #ifndef __compiler_H #define __compiler_H /* - * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2010 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 @@ -74,7 +74,6 @@ extern unsigned recursive_mod_limit; /* Implicit definitions of wires. */ extern bool warn_implicit; -extern bool error_implicit; /* inherit timescales across files. */ extern bool warn_timescale; diff --git a/elab_expr.cc b/elab_expr.cc index f5740171e4..fa165569a6 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2114,22 +2114,6 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, } } - if (error_implicit==false - && sys_task_arg==false - && path_.size()==1 - && scope->default_nettype() != NetNet::NONE) { - NetNet::Type nettype = scope->default_nettype(); - net = new NetNet(scope, peek_tail_name(path_), nettype, 1); - net->data_type(IVL_VT_LOGIC); - net->set_line(*this); - if (warn_implicit) { - cerr << get_fileline() << ": warning: implicit " - "definition of wire " << scope_path(scope) - << "." << peek_tail_name(path_) << "." << endl; - } - return elaborate_expr_net(des, scope, net, scope, sys_task_arg); - } - // 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. diff --git a/elab_net.cc b/elab_net.cc index 18154557b7..d304b0bed5 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2010 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 @@ -170,29 +170,6 @@ NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const return elaborate_lnet_common_(des, scope, true); } -/* - * A private method to create an implicit net. - */ -NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const -{ - NetNet::Type nettype = scope->default_nettype(); - assert(nettype != NetNet::NONE); - - NetNet*sig = new NetNet(scope, peek_tail_name(path_), - nettype, 1); - sig->set_line(*this); - /* Implicit nets are always scalar logic. */ - sig->data_type(IVL_VT_LOGIC); - - if (warn_implicit) { - cerr << get_fileline() << ": warning: implicit " - "definition of wire logic " << scope_path(scope) - << "." << peek_tail_name(path_) << "." << endl; - } - - return sig; -} - /* * This private method evaluates the part selects (if any) for the * signal. The sig argument is the NetNet already located for the diff --git a/elab_scope.cc b/elab_scope.cc index f4f54f5412..a09095c2d6 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2010 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 @@ -1294,7 +1294,6 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s my_scope->set_line(get_file(), mod->get_file(), get_lineno(), mod->get_lineno()); my_scope->set_module_name(mod->mod_name()); - my_scope->default_nettype(mod->default_nettype); instances[idx] = my_scope; diff --git a/elab_sig.cc b/elab_sig.cc index bae8cbefeb..eceb6501ec 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2010 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 @@ -248,68 +248,6 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const return flag; } -bool PExpr::elaborate_sig(Design*des, NetScope*scope) const -{ - return true; -} - -bool PEConcat::elaborate_sig(Design*des, NetScope*scope) const -{ - bool flag = true; - for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) - flag = parms_[idx]->elaborate_sig(des, scope) && flag; - - return flag; -} - -bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const -{ - NetNet* sig = 0; - const NetExpr*par = 0; - NetEvent* eve = 0; - - // If implicit net creation is turned off, then stop now. - if (scope->default_nettype() == NetNet::NONE) - return true; - if (error_implicit) - return true; - - symbol_search(this, des, scope, path_, sig, par, eve); - - if (eve != 0) - return false; - - if (par != 0) - return true; - - if (sig == 0) - sig = make_implicit_net_(des, scope); - - return sig != 0; -} - -bool PEBinary::elaborate_sig(Design*des, NetScope*scope) const -{ - bool flag = true; - - flag = left_->elaborate_sig(des, scope) && flag; - flag = right_->elaborate_sig(des, scope) && flag; - return flag; -} - -bool PETernary::elaborate_sig(Design*des, NetScope*scope) const -{ - bool flag = true; - flag = tru_->elaborate_sig(des, scope) && flag; - flag = fal_->elaborate_sig(des, scope) && flag; - return flag; -} - -bool PEUnary::elaborate_sig(Design*des, NetScope*scope) const -{ - return expr_->elaborate_sig(des, scope); -} - bool PGate::elaborate_sig(Design*des, NetScope*scope) const { return true; @@ -317,33 +255,11 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const bool PGBuiltin::elaborate_sig(Design*des, NetScope*scope) const { - bool flag = true; - - for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { - const PExpr* pin_expr = pin(idx); - if (pin_expr == 0) { - // If there is no pin expression for this port, - // then skip it. Do not bother generating an error - // message here, that will be done during - // elaboration where these semantic details are tested. - continue; - } - ivl_assert(*this, pin_expr); - flag = pin_expr->elaborate_sig(des, scope) && flag; - } - - return flag; + return true; } bool PGAssign::elaborate_sig(Design*des, NetScope*scope) const { - /* Normally, l-values to continuous assignments are NOT allowed - to implicitly declare nets. However, so many tools do allow - it that Icarus Verilog will allow it, at least if extensions - are enabled. */ - if (gn_icarus_misc_flag) - return pin(0)->elaborate_sig(des, scope); - return true; } @@ -352,25 +268,6 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope, { bool flag = true; - // First, elaborate the signals that may be created implicitly - // by ports to this module instantiation. Handle the case that - // the ports are passed by name (pins_ != 0) or position. - if (pins_) - for (unsigned idx = 0 ; idx < npins_ ; idx += 1) { - const PExpr*tmp = pins_[idx].parm; - if (tmp == 0) - continue; - flag = tmp->elaborate_sig(des, scope) && flag; - } - else - for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { - const PExpr*tmp = pin(idx); - if (tmp == 0) - continue; - flag = tmp->elaborate_sig(des, scope) && flag; - } - - NetScope::scope_vec_t instance = scope->instance_arrays[get_name()]; for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) { @@ -398,24 +295,7 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope, bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const { - bool flag = true; - - if (pins_) - for (unsigned idx = 0 ; idx < npins_ ; idx += 1) { - const PExpr*tmp = pins_[idx].parm; - if (tmp == 0) - continue; - flag = tmp->elaborate_sig(des, scope) && flag; - } - else - for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { - const PExpr*tmp = pin(idx); - if (tmp == 0) - continue; - flag = tmp->elaborate_sig(des, scope) && flag; - } - - return flag; + return true; } bool PGenerate::elaborate_sig(Design*des, NetScope*container) const diff --git a/elaborate.cc b/elaborate.cc index d85f9a1cc8..a947474c86 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 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 @@ -3064,15 +3064,12 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, } } - bool save_flag = error_implicit; - error_implicit = true; probe_expr_width(des, scope, expr_[idx]->expr()); NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), 0); if (tmp == 0) { expr_[idx]->dump(cerr); cerr << endl; des->errors += 1; - error_implicit = save_flag; continue; } @@ -3082,14 +3079,12 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, expr_[idx]->dump(cerr); cerr << endl; des->errors += 1; - error_implicit = save_flag; continue; } assert(expr); delete tmp; - error_implicit = save_flag; unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE) ? expr->pin_count() : 1; @@ -4001,7 +3996,6 @@ static void elaborate_tasks(Design*des, NetScope*scope, bool Module::elaborate(Design*des, NetScope*scope) const { bool result_flag = true; - error_implicit = true; if (gn_specify_blocks_flag) { // Elaborate specparams @@ -4068,7 +4062,6 @@ bool Module::elaborate(Design*des, NetScope*scope) const // complex. const list&gl = get_gates(); - error_implicit = false; for (list::const_iterator gt = gl.begin() ; gt != gl.end() ; gt ++ ) { @@ -4076,8 +4069,6 @@ bool Module::elaborate(Design*des, NetScope*scope) const (*gt)->elaborate(des, scope); } - error_implicit = true; - // Elaborate the behaviors, making processes out of them. This // involves scanning the PProcess* list, creating a NetProcTop // for each process. @@ -4387,7 +4378,6 @@ Design* elaborate(listroots) scope->time_unit(rmod->time_unit); scope->time_precision(rmod->time_precision); scope->time_from_timescale(rmod->time_from_timescale); - scope->default_nettype(rmod->default_nettype); des->set_precision(rmod->time_precision); diff --git a/main.cc b/main.cc index 815deaa0a2..0bd0fbd568 100644 --- a/main.cc +++ b/main.cc @@ -1,6 +1,6 @@ const char COPYRIGHT[] = - "Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)"; + "Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)"; /* * This source code is free software; you can redistribute it @@ -135,8 +135,6 @@ bool warn_ob_select = false; bool warn_sens_entire_vec = false; bool warn_sens_entire_arr = false; -bool error_implicit = false; - /* * Debug message class flags. */ diff --git a/net_scope.cc b/net_scope.cc index 216cc5db8f..0e2896461e 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2010 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 @@ -44,14 +44,12 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t) is_cell_ = false; if (up) { - default_nettype_ = up->default_nettype(); time_unit_ = up->time_unit(); time_prec_ = up->time_precision(); time_from_timescale_ = up->time_from_timescale(); // Need to check for duplicate names? up_->children_[name_] = this; } else { - default_nettype_ = NetNet::NONE; time_unit_ = 0; time_prec_ = 0; time_from_timescale_ = false; @@ -354,16 +352,6 @@ bool NetScope::time_from_timescale() const return time_from_timescale_; } -void NetScope::default_nettype(NetNet::Type nt) -{ - default_nettype_ = nt; -} - -NetNet::Type NetScope::default_nettype() const -{ - return default_nettype_; -} - perm_string NetScope::basename() const { return name_.peek_name(); diff --git a/netlist.h b/netlist.h index 2c9544bd97..a9e38e7447 100644 --- a/netlist.h +++ b/netlist.h @@ -1,7 +1,7 @@ #ifndef __netlist_H #define __netlist_H /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 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 @@ -805,9 +805,6 @@ class NetScope : public Attrib { int time_precision() const; bool time_from_timescale() const; - void default_nettype(NetNet::Type); - NetNet::Type default_nettype() const; - /* The fullname of the scope is the hierarchical name component (which includes the name and array index) whereas the basename is just my name. */ @@ -912,7 +909,6 @@ class NetScope : public Attrib { signed char time_unit_, time_prec_; bool time_from_timescale_; - NetNet::Type default_nettype_; NetEvent *events_; diff --git a/pform.cc b/pform.cc index 7320e78f33..88462bbd37 100644 --- a/pform.cc +++ b/pform.cc @@ -363,10 +363,6 @@ static bool pform_at_module_level() PWire*pform_get_wire_in_scope(perm_string name) { - /* Note that if we are processing a generate, then the - scope depth will be empty because generate schemes - cannot be within sub-scopes. Only directly in - modules. */ return lexical_scope->wires_find(name); } @@ -403,6 +399,16 @@ void pform_set_default_nettype(NetNet::Type type, } } +static void pform_declare_implicit_nets(PExpr*expr) +{ + /* If implicit net creation is turned off, then stop now. */ + if (pform_default_nettype == NetNet::NONE) + return; + + if (expr) + expr->declare_implicit_nets(lexical_scope, pform_default_nettype); +} + /* * The lexor calls this function to set the active timescale when it * detects a `timescale directive. The function saves the directive @@ -667,7 +673,6 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno, /* If we have a timescale file then the time information is from * a timescale directive. */ pform_cur_module->time_from_timescale = pform_timescale_file != 0; - pform_cur_module->default_nettype = pform_default_nettype; FILE_NAME(pform_cur_module, file, lineno); pform_cur_module->library_flag = pform_library_flag; @@ -1481,6 +1486,10 @@ void pform_makegate(PGBuiltin::Type type, return; } + for (unsigned idx = 0 ; idx < info.parms->count() ; idx += 1) { + pform_declare_implicit_nets((*info.parms)[idx]); + } + perm_string dev_name = lex_strings.make(info.name); PGBuiltin*cur = new PGBuiltin(type, dev_name, info.parms, delay); if (info.range[0]) @@ -1545,6 +1554,10 @@ static void pform_make_modgate(perm_string type, PExpr*msb, PExpr*lsb, const char*fn, unsigned ln) { + for (unsigned idx = 0 ; idx < wires->count() ; idx += 1) { + pform_declare_implicit_nets((*wires)[idx]); + } + PGModule*cur = new PGModule(type, name, wires); FILE_NAME(cur, fn, ln); cur->set_range(msb,lsb); @@ -1584,6 +1597,7 @@ static void pform_make_modgate(perm_string type, named_pexpr_t*curp = (*bind)[idx]; pins[idx].name = curp->name; pins[idx].parm = curp->parm; + pform_declare_implicit_nets(curp->parm); } PGModule*cur = new PGModule(type, name, pins, npins); @@ -1659,6 +1673,11 @@ static PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval, svector*del, struct str_pair_t str) { + /* Implicit declaration of nets on the LHS of a continuous + assignment was introduced in IEEE1364-2001. */ + if (generation_flag != GN_VER1995) + pform_declare_implicit_nets(lval); + svector*wires = new svector(2); (*wires)[0] = lval; (*wires)[1] = rval;