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;