From f6507cba431ff33a33402106c27b82bc319aabfb Mon Sep 17 00:00:00 2001 From: steve Date: Wed, 6 Dec 2000 06:31:09 +0000 Subject: [PATCH] Check lvalue of procedural continuous assign (PR#29) --- Makefile.in | 8 +-- PExpr.h | 17 +++++- elab_anet.cc | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++ elaborate.cc | 7 ++- parse.y | 4 +- 5 files changed, 182 insertions(+), 9 deletions(-) create mode 100644 elab_anet.cc diff --git a/Makefile.in b/Makefile.in index e699ff697..179c94265 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.86 2000/12/04 17:37:03 steve Exp $" +#ident "$Id: Makefile.in,v 1.87 2000/12/06 06:31:09 steve Exp $" # # SHELL = /bin/sh @@ -86,12 +86,12 @@ TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-vvm.o t-xnf.o FF = nodangle.o synth.o syn-rules.o xnfio.o O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ -elab_lval.o elab_net.o elab_pexpr.o elab_scope.o elab_sig.o emit.o eval.o \ +elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \ +elab_sig.o emit.o eval.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ mangle.o netlist.o net_assign.o \ net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \ -net_scope.o net_udp.o \ -pad_to_width.o \ +net_scope.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ verinum.o verireal.o target.o targets.o util.o \ diff --git a/PExpr.h b/PExpr.h index 1dd88a7b0..de3489833 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PExpr.h,v 1.44 2000/09/17 21:26:15 steve Exp $" +#ident "$Id: PExpr.h,v 1.45 2000/12/06 06:31:09 steve Exp $" #endif # include @@ -71,6 +71,10 @@ class PExpr : public LineInfo { Link::strength_t drive1 =Link::STRONG) const; + // This method elaborates the expression as NetNet objects. It + // only allows regs suitable for procedural continuous assignments. + virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; + // This method elaborates the expression as gates, but // restricted for use as l-values of continuous assignments. virtual NetNet* elaborate_lnet(Design*des, const string&path) const; @@ -109,6 +113,11 @@ class PEConcat : public PExpr { ~PEConcat(); virtual void dump(ostream&) const; + + // Concatenated Regs can be on the left of procedural + // continuous assignments. + virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; + virtual NetNet* elaborate_lnet(Design*des, const string&path) const; virtual NetNet* elaborate_net(Design*des, const string&path, unsigned width, @@ -162,6 +171,9 @@ class PEIdent : public PExpr { virtual void dump(ostream&) const; + // Regs can be on the left of procedural continuous assignments + virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const; + // Identifiers are allowed (with restrictions) is assign l-values. virtual NetNet* elaborate_lnet(Design*des, const string&path) const; @@ -397,6 +409,9 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.45 2000/12/06 06:31:09 steve + * Check lvalue of procedural continuous assign (PR#29) + * * Revision 1.44 2000/09/17 21:26:15 steve * Add support for modulus (Eric Aardoom) * diff --git a/elab_anet.cc b/elab_anet.cc new file mode 100644 index 000000000..41c724e4b --- /dev/null +++ b/elab_anet.cc @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com.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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: elab_anet.cc,v 1.1 2000/12/06 06:31:09 steve Exp $" +#endif + +/* + * The elaborate_anet methods elaborate expressions that are intended + * to be the left side of procedural continuous assignments. + */ + +# include "PExpr.h" +# include "netlist.h" +# include + +NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const +{ + cerr << get_line() << ": error: Invalid expression on left side " + << "of precedural continuous asignment." << endl; + return 0; +} + + +NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const +{ + if (repeat_) { + cerr << get_line() << ": error: Repeat concatenations make " + "no sense in l-value expressions. I refuse." << endl; + des->errors += 1; + return 0; + } + + svectornets (parms_.count()); + unsigned pins = 0; + unsigned errors = 0; + + for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) { + + if (parms_[idx] == 0) { + cerr << get_line() << ": error: Empty expressions " + << "not allowed in concatenations." << endl; + errors += 1; + continue; + } + + nets[idx] = parms_[idx]->elaborate_anet(des, scope); + if (nets[idx] == 0) + errors += 1; + else + pins += nets[idx]->pin_count(); + } + + /* If any of the sub expressions failed to elaborate, then + delete all those that did and abort myself. */ + if (errors) { + for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) { + if (nets[idx]) delete nets[idx]; + } + des->errors += 1; + return 0; + } + + /* Make the temporary signal that connects to all the + operands, and connect it up. Scan the operands of the + concat operator from least significant to most significant, + which is opposite from how they are given in the list. + + Allow for a repeat count other then 1 by repeating the + connect loop as many times as necessary. */ + + NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()), + NetNet::IMPLICIT_REG, pins); + + pins = 0; + for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) { + NetNet*cur = nets[idx-1]; + for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) { + connect(osig->pin(pins), cur->pin(pin)); + pins += 1; + } + } + + osig->local_flag(true); + return osig; +} + +NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const +{ + NetNet*sig = des->find_signal(scope, text_); + + if (sig == 0) { + if (NetMemory*mem = des->find_memory(scope, text_)) { + cerr << get_line() << ": error: memories not allowed " + << "on left side of procedural continuous " + << "asignment." << endl; + des->errors += 1; + return 0; + } + + cerr << get_line() << ": error: reg ``" << text_ << "'' " + << "is undefined in this scope." << endl; + des->errors += 1; + return 0; + } + + switch (sig->type()) { + case NetNet::REG: + case NetNet::IMPLICIT_REG: + case NetNet::INTEGER: + break; + + default: + cerr << get_line() << ": error: " << text_ << " is not " + << "a reg in this context." << endl; + des->errors += 1; + return 0; + } + + assert(sig); + + if (msb_ || lsb_) { + + cerr << get_line() << ": error: bit/part selects not allowed " + << "on left side of procedural continuous asignment." + << endl; + des->errors += 1; + return 0; + } + + return sig; +} + +/* + * $Log: elab_anet.cc,v $ + * Revision 1.1 2000/12/06 06:31:09 steve + * Check lvalue of procedural continuous assign (PR#29) + * + */ + diff --git a/elaborate.cc b/elaborate.cc index a42482651..90a0a2dab 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.198 2000/12/01 23:52:49 steve Exp $" +#ident "$Id: elaborate.cc,v 1.199 2000/12/06 06:31:09 steve Exp $" #endif /* @@ -1487,7 +1487,7 @@ NetCAssign* PCAssign::elaborate(Design*des, const string&path) const NetScope*scope = des->find_scope(path); assert(scope); - NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0); + NetNet*lval = lval_->elaborate_anet(des, scope); if (lval == 0) return 0; @@ -2333,6 +2333,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.199 2000/12/06 06:31:09 steve + * Check lvalue of procedural continuous assign (PR#29) + * * Revision 1.198 2000/12/01 23:52:49 steve * Handle null statements inside a wait. (PR#60) * diff --git a/parse.y b/parse.y index 51fdf78a3..8d787ba43 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: parse.y,v 1.110 2000/12/05 22:32:05 steve Exp $" +#ident "$Id: parse.y,v 1.111 2000/12/06 06:31:09 steve Exp $" #endif # include "parse_misc.h" @@ -1797,7 +1797,7 @@ statement $$ = tmp; } - | K_deassign lavalue';' + | K_deassign lavalue ';' { PDeassign*tmp = new PDeassign($2); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line);