diff --git a/Attrib.cc b/Attrib.cc index b34f285d5..f82b4293d 100644 --- a/Attrib.cc +++ b/Attrib.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $" +#ident "$Id: Attrib.cc,v 1.3 2002/05/23 03:08:50 steve Exp $" #endif # include "config.h" @@ -36,14 +36,15 @@ Attrib::~Attrib() delete[] list_; } -void Attrib::set_attributes(const map&attr) +#if 0 +void Attrib::copy_attributes(const map&attr) { assert(list_ == 0); nlist_ = attr.size(); list_ = new cell_[nlist_]; - map::const_iterator idx; + map::const_iterator idx; unsigned jdx; for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) { struct cell_*tmp = list_ + jdx; @@ -51,8 +52,9 @@ void Attrib::set_attributes(const map&attr) tmp->val = (*idx).second; } } +#endif -string Attrib::attribute(const string&key) const +const verinum& Attrib::attribute(const string&key) const { for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) { @@ -60,10 +62,11 @@ string Attrib::attribute(const string&key) const return list_[idx].val; } - return ""; + static const verinum null; + return null; } -void Attrib::attribute(const string&key, const string&value) +void Attrib::attribute(const string&key, const verinum&value) { unsigned idx; @@ -92,7 +95,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const for (idx = 0 ; idx < that.nlist_ ; idx += 1) { - string tmp = attribute(that.list_[idx].key); + verinum tmp = attribute(that.list_[idx].key); if (tmp != that.list_[idx].val) return false; } @@ -111,7 +114,7 @@ string Attrib::key(unsigned idx) const return list_[idx].key; } -string Attrib::value(unsigned idx) const +const verinum& Attrib::value(unsigned idx) const { assert(idx < nlist_); return list_[idx].val; @@ -120,6 +123,14 @@ string Attrib::value(unsigned idx) const /* * $Log: Attrib.cc,v $ + * Revision 1.3 2002/05/23 03:08:50 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.2 2001/07/25 03:10:48 steve * Create a config.h.in file to hold all the config * junk, and support gcc 3.0. (Stephan Boettcher) diff --git a/Attrib.h b/Attrib.h index f7479182c..dd77cbf17 100644 --- a/Attrib.h +++ b/Attrib.h @@ -19,11 +19,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $" +#ident "$Id: Attrib.h,v 1.2 2002/05/23 03:08:50 steve Exp $" #endif # include # include +# include "verinum.h" /* * This class keeps a map of key/value pairs. The map can be set from @@ -35,21 +36,21 @@ class Attrib { Attrib(); ~Attrib(); - void set_attributes(const map&attr); - string attribute(const string&key) const; - void attribute(const string&key, const string&value); + const verinum&attribute(const string&key) const; + void attribute(const string&key, const verinum&value); bool has_compat_attributes(const Attrib&that) const; /* Provide a means of iterating over the entries in the map. */ unsigned size() const; string key(unsigned idx) const; - string value(unsigned idx) const; + const verinum& value(unsigned idx) const; + private: struct cell_ { - string key; - string val; + string key; + verinum val; }; unsigned nlist_; @@ -62,6 +63,14 @@ class Attrib { /* * $Log: Attrib.h,v $ + * Revision 1.2 2002/05/23 03:08:50 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.1 2000/12/04 17:37:03 steve * Add Attrib class for holding NetObj attributes. * diff --git a/Makefile.in b/Makefile.in index 4d3d1b35a..12cb54868 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.122 2002/05/19 05:21:00 steve Exp $" +#ident "$Id: Makefile.in,v 1.123 2002/05/23 03:08:50 steve Exp $" # # SHELL = /bin/sh @@ -126,7 +126,7 @@ 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_anet.o elab_pexpr.o elab_scope.o \ -elab_sig.o emit.o eval.o eval_rconst.o \ +elab_sig.o emit.o eval.o eval_attrib.o eval_rconst.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o netlist.o netmisc.o net_assign.o \ net_design.o net_event.o net_expr.o net_force.o net_func.o \ diff --git a/PExpr.h b/PExpr.h index 642f08765..b21c9ad64 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.59 2002/04/23 03:53:59 steve Exp $" +#ident "$Id: PExpr.h,v 1.60 2002/05/23 03:08:51 steve Exp $" #endif # include @@ -328,6 +328,7 @@ class PEString : public PExpr { virtual NetEConst*elaborate_expr(Design*des, NetScope*, bool sys_task_arg =false) const; virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const; + verinum* PEString::eval_const(const Design*, const NetScope*) const; virtual bool is_constant(Module*) const; @@ -496,6 +497,14 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.60 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.59 2002/04/23 03:53:59 steve * Add support for non-constant bit select. * diff --git a/PGate.h b/PGate.h index a8062dff2..0b5877f5e 100644 --- a/PGate.h +++ b/PGate.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $" +#ident "$Id: PGate.h,v 1.23 2002/05/23 03:08:51 steve Exp $" #endif # include "svector.h" @@ -79,7 +79,7 @@ class PGate : public LineInfo { void strength0(strength_t); void strength1(strength_t); - map attributes; + map attributes; virtual void dump(ostream&out) const; virtual void elaborate(Design*des, NetScope*scope) const; @@ -222,6 +222,14 @@ class PGModule : public PGate { /* * $Log: PGate.h,v $ + * Revision 1.23 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.22 2001/11/22 06:20:59 steve * Use NetScope instead of string for scope path. * diff --git a/PUdp.h b/PUdp.h index ae6784d9a..e5cc0f3ad 100644 --- a/PUdp.h +++ b/PUdp.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $" +#ident "$Id: PUdp.h,v 1.6 2002/05/23 03:08:51 steve Exp $" #endif # include @@ -27,6 +27,8 @@ # include # include "verinum.h" +class PExpr; + svector::svector(unsigned size) : nitems_(size), items_(new string[size]) { @@ -68,7 +70,7 @@ class PUdp { verinum::V initial; - map attributes; + map attributes; void dump(ostream&out) const; @@ -82,6 +84,14 @@ class PUdp { /* * $Log: PUdp.h,v $ + * Revision 1.6 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.5 2001/04/22 23:09:45 steve * More UDP consolidation from Stephan Boettcher. * diff --git a/PWire.h b/PWire.h index 8f9acbdcd..7bb58b244 100644 --- a/PWire.h +++ b/PWire.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $" +#ident "$Id: PWire.h,v 1.12 2002/05/23 03:08:51 steve Exp $" #endif # include "netlist.h" @@ -69,7 +69,7 @@ class PWire : public LineInfo { void set_memory_idx(PExpr*ldx, PExpr*rdx); - map attributes; + map attributes; // Write myself to the specified stream. void dump(ostream&out) const; @@ -99,6 +99,14 @@ class PWire : public LineInfo { /* * $Log: PWire.h,v $ + * Revision 1.12 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.11 2001/12/03 04:47:14 steve * Parser and pform use hierarchical names as hname_t * objects instead of encoded strings. diff --git a/cprop.cc b/cprop.cc index d3dd4cd97..064bc8488 100644 --- a/cprop.cc +++ b/cprop.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: cprop.cc,v 1.33 2002/04/14 02:51:37 steve Exp $" +#ident "$Id: cprop.cc,v 1.34 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -56,7 +56,7 @@ void cprop_functor::signal(Design*des, NetNet*obj) void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj) { // For now, only additions are handled. - if (obj->attribute("LPM_Direction") != "ADD") + if (obj->attribute("LPM_Direction") != verinum("ADD")) return; // If the low bit on the A side is 0, then eliminate it from @@ -949,6 +949,14 @@ void cprop(Design*des) /* * $Log: cprop.cc,v $ + * Revision 1.34 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.33 2002/04/14 02:51:37 steve * Fix bug removing pairs of ones in XOR. * diff --git a/elab_net.cc b/elab_net.cc index 2e5c439c1..1f5f2f570 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_net.cc,v 1.89 2002/04/23 03:53:59 steve Exp $" +#ident "$Id: elab_net.cc,v 1.90 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -240,10 +240,10 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope, switch (op_) { case '+': - gate->attribute("LPM_Direction", "ADD"); + gate->attribute("LPM_Direction", verinum("ADD")); break; case '-': - gate->attribute("LPM_Direction", "SUB"); + gate->attribute("LPM_Direction", verinum("SUB")); break; } @@ -2102,6 +2102,14 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.90 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.89 2002/04/23 03:53:59 steve * Add support for non-constant bit select. * diff --git a/elab_sig.cc b/elab_sig.cc index 9fc4dae99..99a03045b 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_sig.cc,v 1.21 2002/05/19 23:37:28 steve Exp $" +#ident "$Id: elab_sig.cc,v 1.22 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -475,6 +475,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const } + unsigned nattrib = 0; + attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib, + des, scope); + if (lidx_ || ridx_) { assert(lidx_ && ridx_); @@ -513,12 +517,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const sig->set_line(*this); sig->port_type(port_type_); sig->set_signed(get_signed()); - sig->set_attributes(attributes); + + for (unsigned idx = 0 ; idx < nattrib ; idx += 1) + sig->attribute(attrib_list[idx].key, attrib_list[idx].val); } } /* * $Log: elab_sig.cc,v $ + * Revision 1.22 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.21 2002/05/19 23:37:28 steve * Parse port_declaration_lists from the 2001 Standard. * diff --git a/elaborate.cc b/elaborate.cc index 09a40f376..06e211e4c 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.248 2002/05/12 19:16:58 steve Exp $" +#ident "$Id: elaborate.cc,v 1.249 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -40,6 +40,7 @@ # include "parse_api.h" # include "compiler.h" + static Link::strength_t drive_type(PGate::strength_t drv) { switch (drv) { @@ -265,6 +266,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const unsigned long rise_time, fall_time, decay_time; eval_delays(des, scope, rise_time, fall_time, decay_time); + struct attrib_list_t*attrib_list = 0; + unsigned attrib_list_n = 0; + attrib_list = evaluate_attributes(attributes, attrib_list_n, + des, scope); + /* Now make as many gates as the bit count dictates. Give each a unique name, and set the delay times. */ @@ -359,7 +365,10 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const return; } - cur[idx]->set_attributes(attributes); + for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) + cur[idx]->attribute(attrib_list[adx].key, + attrib_list[adx].val); + cur[idx]->rise_time(rise_time); cur[idx]->fall_time(fall_time); cur[idx]->decay_time(decay_time); @@ -370,6 +379,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const des->add_node(cur[idx]); } + + delete[]attrib_list; + /* The gates have all been allocated, this loop runs through the parameters and attaches the ports of the objects. */ @@ -676,11 +688,20 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); - net->set_attributes(udp->attributes); net->rise_time(rise_time); net->fall_time(fall_time); net->decay_time(decay_time); + struct attrib_list_t*attrib_list = 0; + unsigned attrib_list_n = 0; + attrib_list = evaluate_attributes(attributes, attrib_list_n, + des, scope); + + for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) + net->attribute(attrib_list[adx].key, attrib_list[adx].val); + + delete[]attrib_list; + /* Run through the pins, making netlists for the pin expressions and connecting them to the pin in question. All of this is independent of the nature of the UDP. */ @@ -2530,6 +2551,14 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.249 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.248 2002/05/12 19:16:58 steve * Accept errors in memory index expression. * diff --git a/eval.cc b/eval.cc index bd3dadc81..77b005872 100644 --- a/eval.cc +++ b/eval.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: eval.cc,v 1.26 2001/12/29 22:10:10 steve Exp $" +#ident "$Id: eval.cc,v 1.27 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -166,6 +166,11 @@ verinum* PENumber::eval_const(const Design*, const NetScope*) const return new verinum(value()); } +verinum* PEString::eval_const(const Design*, const NetScope*) const +{ + return new verinum(string(text_)); +} + verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const { verinum*test = expr_->eval_const(des, scope); @@ -217,6 +222,14 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const /* * $Log: eval.cc,v $ + * Revision 1.27 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.26 2001/12/29 22:10:10 steve * constant eval of arithmetic with x and z. * diff --git a/eval_attrib.cc b/eval_attrib.cc new file mode 100644 index 000000000..a5a1dd7b4 --- /dev/null +++ b/eval_attrib.cc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2002 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 + * 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) +#ident "$Id: eval_attrib.cc,v 1.1 2002/05/23 03:08:51 steve Exp $" +#endif + +# include "util.h" +# include "PExpr.h" +# include "netlist.h" +# include + +/* + * The evaluate_attributes function evaluates the attribute + * expressions from the map, and resturns a table in a form suitable + * for passing to netlist devices. + */ + +attrib_list_t* evaluate_attributes(const map&att, + unsigned&natt, + const Design*des, + const NetScope*scope) +{ + natt = att.size(); + if (natt == 0) + return 0; + + attrib_list_t*table = new attrib_list_t [natt]; + + unsigned idx = 0; + + typedef map::const_iterator iter_t; + for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) { + table[idx].key = (*cur).first; + PExpr*exp = (*cur).second; + + verinum*tmp; + if (exp) + tmp = exp->eval_const(des, scope); + else + tmp = new verinum(); + + if (tmp == 0) + cerr << "internal error: no result for " << *exp << endl; + assert(tmp); + + table[idx].val = *tmp; + delete tmp; + } + + assert(idx == natt); + return table; +} + +/* + * $Log: eval_attrib.cc,v $ + * Revision 1.1 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * + */ + diff --git a/expr_synth.cc b/expr_synth.cc index ba7790ed0..28c1ceeb1 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: expr_synth.cc,v 1.31 2001/12/30 17:06:52 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.32 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -62,10 +62,10 @@ NetNet* NetEBAdd::synthesize(Design*des) switch (op()) { case '+': - adder->attribute("LPM_Direction", "ADD"); + adder->attribute("LPM_Direction", verinum("ADD")); break; case '-': - adder->attribute("LPM_Direction", "SUB"); + adder->attribute("LPM_Direction", verinum("SUB")); break; } @@ -587,6 +587,14 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.32 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.31 2001/12/30 17:06:52 steve * Synthesize reduction logic. * diff --git a/ivl.def b/ivl.def index 5df4a4471..241b5dafc 100644 --- a/ivl.def +++ b/ivl.def @@ -43,6 +43,8 @@ ivl_expr_uvalue ivl_expr_width ivl_logic_attr +ivl_logic_attr_cnt +ivl_logic_attr_val ivl_logic_delay ivl_logic_name ivl_logic_basename diff --git a/ivl_target.h b/ivl_target.h index 609131367..f9ff14f1c 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.94 2002/03/17 19:30:20 steve Exp $" +#ident "$Id: ivl_target.h,v 1.95 2002/05/23 03:08:51 steve Exp $" #endif #ifdef __cplusplus @@ -300,6 +300,24 @@ typedef int (*ivl_process_f)(ivl_process_t net, void*cd); the user passes to the scanner. */ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd); +/* Attributes, which can be attached to various object types, have + this form. */ +typedef enum ivl_attribute_type_e { + IVL_ATT_VOID = 0, + IVL_ATT_STR, + IVL_ATT_NUM +} ivl_attribute_type_t; + +struct ivl_attribute_s { + const char*key; + ivl_attribute_type_t type; + union val_ { + const char*str; + long num; + } val; +}; +typedef const struct ivl_attribute_s*ivl_attribute_t; + /* DESIGN * When handed a design (ivl_design_t) there are a few things that you @@ -480,6 +498,12 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net); * ivl_logic_attr * Return the value of a specific attribute, given the key name as * a string. If the key is not defined, then return 0 (null). + * + * ivl_logic_attr_cnt + * ivl_logic_attr_val + * These support iterating over logic attributes. The _cnt method + * returns the number of attributes attached to the gate, and the + * ivl_logic_attr_val returns the value of the attribute. */ extern const char* ivl_logic_name(ivl_net_logic_t net); @@ -491,8 +515,12 @@ extern unsigned ivl_logic_pins(ivl_net_logic_t net); extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net); extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition); + /* DEPRICATED */ extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key); +extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net); +extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx); + /* UDP * */ @@ -1006,6 +1034,14 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.95 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.94 2002/03/17 19:30:20 steve * Add API to support user defined function. * diff --git a/lexor.lex b/lexor.lex index 251ddec2b..09296cdee 100644 --- a/lexor.lex +++ b/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: lexor.lex,v 1.71 2002/04/15 00:04:22 steve Exp $" +#ident "$Id: lexor.lex,v 1.72 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -128,14 +128,9 @@ W [ \t\b\f\r]+ \n { yylloc.first_line += 1; yymore(); } "*/" { BEGIN(comment_enter); } - /* Pragma comments are very similar to C-style comments, except that - they are allowed to carry tool-specific pragma strings. */ - -"(*" { comment_enter = YY_START; BEGIN(PCOMMENT); } -. { yymore(); } -\n { yylloc.first_line += 1; yymore(); } -"*)" { BEGIN(comment_enter); } +"(*" { return K_PSTAR; } +"*)" { return K_STARP; } "<<" { return K_LS; } ">>" { return K_RS; } "<=" { return K_LE; } diff --git a/netlist.cc b/netlist.cc index bd158a9ab..e45daa957 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.185 2002/05/05 21:11:50 steve Exp $" +#ident "$Id: netlist.cc,v 1.186 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -205,17 +205,12 @@ const NetScope* NetObj::scope() const return scope_; } -void NetObj::set_attributes(const map&attr) -{ - attributes_.set_attributes(attr); -} - -string NetObj::attribute(const string&key) const +const verinum& NetObj::attribute(const string&key) const { return attributes_.attribute(key); } -void NetObj::attribute(const string&key, const string&value) +void NetObj::attribute(const string&key, const verinum&value) { attributes_.attribute(key, value); } @@ -235,9 +230,9 @@ const char* NetObj::attr_key(unsigned idx) const return attributes_.key(idx).c_str(); } -const char* NetObj::attr_value(unsigned idx) const +const verinum& NetObj::attr_value(unsigned idx) const { - return attributes_.value(idx).c_str(); + return attributes_.value(idx); } @@ -2359,6 +2354,14 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.186 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.185 2002/05/05 21:11:50 steve * Put off evaluation of concatenation repeat expresions * until after parameters are defined. This allows parms diff --git a/netlist.h b/netlist.h index 633d1cfc6..13ef7080d 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.236 2002/05/05 21:11:50 steve Exp $" +#ident "$Id: netlist.h,v 1.237 2002/05/23 03:08:51 steve Exp $" #endif /* @@ -101,9 +101,8 @@ class NetObj { void fall_time(unsigned d) { delay2_ = d; } void decay_time(unsigned d) { delay3_ = d; } - void set_attributes(const map&); - string attribute(const string&key) const; - void attribute(const string&key, const string&value); + const verinum& attribute(const string&key) const; + void attribute(const string&key, const verinum&value); // Return true if this has all the attributes in that and they // all have the same values. @@ -111,7 +110,7 @@ class NetObj { unsigned nattr() const; const char* attr_key(unsigned) const; - const char* attr_value(unsigned) const; + const verinum& attr_value(unsigned) const; Link&pin(unsigned idx); const Link&pin(unsigned idx) const; @@ -2980,6 +2979,14 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.237 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.236 2002/05/05 21:11:50 steve * Put off evaluation of concatenation repeat expresions * until after parameters are defined. This allows parms diff --git a/parse.y b/parse.y index 4646d3f00..e0c8b4982 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.151 2002/05/20 02:06:01 steve Exp $" +#ident "$Id: parse.y,v 1.152 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -63,8 +63,8 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; Module::port_t *mport; svector*mports; - portname_t*portname; - svector*portnames; + named_pexpr_t*named_pexpr; + svector*named_pexprs; struct parmvalue_t*parmvalue; PExpr*expr; @@ -99,6 +99,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %token REALTIME %token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_SG %token K_PO_POS K_PO_NEG +%token K_PSTAR K_STARP %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER %token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case %token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable @@ -143,8 +144,11 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %type task_item task_item_list task_item_list_opt %type function_item function_item_list -%type port_name parameter_value_byname -%type port_name_list parameter_value_byname_list +%type port_name parameter_value_byname +%type port_name_list parameter_value_byname_list + +%type attribute +%type attribute_list attribute_list_opt %type case_item %type case_items @@ -202,6 +206,55 @@ source_file | source_file description ; + /* Verilog-2001 supports attribute lists, which can be attached to a + variety of different objects. The syntax inside the (* *) is a + comma separated list of names or names with assigned values. */ +attribute_list_opt + : K_PSTAR attribute_list K_STARP { $$ = $2; } + | K_PSTAR K_STARP { $$ = 0; } + | { $$ = 0; } + ; + +attribute_list + : attribute_list ',' attribute + { svector*tmp = + new svector(*$1,$3); + delete $1; + $$ = tmp; + } + | attribute + { svector*tmp = new svector(1); + (*tmp)[0] = $1; + $$ = tmp; + } + ; + + +attribute + : IDENTIFIER + { named_pexpr_t*tmp = new named_pexpr_t; + tmp->name = string($1); + tmp->parm = 0; + delete $1; + $$ = tmp; + } + | IDENTIFIER '=' expression + { PExpr*tmp = $3; + if (!pform_expression_is_constant(tmp)) { + yyerror(@3, "error: attibute value " + "expression must be constant."); + delete tmp; + tmp = 0; + } + named_pexpr_t*tmp2 = new named_pexpr_t; + tmp2->name = string($1); + tmp2->parm = tmp; + delete $1; + $$ = tmp2; + } + ; + + /* The block_item_decl is used in function definitions, task definitions, module definitions and named blocks. Wherever a new scope is entered, the source may declare new registers and @@ -446,7 +499,6 @@ description { pform_set_type_attrib($3, $5, $7); delete $3; delete $5; - delete $7; } ; @@ -1329,38 +1381,40 @@ module_item /* Most gate types have an optional drive strength and optional three-value delay. These rules handle the different cases. */ - | gatetype gate_instance_list ';' - { pform_makegates($1, str_strength, 0, $2); + | attribute_list_opt gatetype gate_instance_list ';' + { pform_makegates($2, str_strength, 0, $3, $1); } - | gatetype delay3 gate_instance_list ';' - { pform_makegates($1, str_strength, $2, $3); + | attribute_list_opt gatetype delay3 gate_instance_list ';' + { pform_makegates($2, str_strength, $3, $4, $1); } - | gatetype drive_strength gate_instance_list ';' - { pform_makegates($1, $2, 0, $3); + | attribute_list_opt gatetype drive_strength gate_instance_list ';' + { pform_makegates($2, $3, 0, $4, $1); } - | gatetype drive_strength delay3 gate_instance_list ';' - { pform_makegates($1, $2, $3, $4); + | attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';' + { pform_makegates($2, $3, $4, $5, $1); } /* Pullup and pulldown devices cannot have delays, and their strengths are limited. */ | K_pullup gate_instance_list ';' - { pform_makegates(PGBuiltin::PULLUP, pull_strength, 0, $2); + { pform_makegates(PGBuiltin::PULLUP, pull_strength, 0, + $2, 0); } | K_pulldown gate_instance_list ';' - { pform_makegates(PGBuiltin::PULLDOWN, pull_strength, 0, $2); + { pform_makegates(PGBuiltin::PULLDOWN, pull_strength, + 0, $2, 0); } | K_pullup '(' dr_strength1 ')' gate_instance_list ';' - { pform_makegates(PGBuiltin::PULLUP, $3, 0, $5); + { pform_makegates(PGBuiltin::PULLUP, $3, 0, $5, 0); } | K_pulldown '(' dr_strength0 ')' gate_instance_list ';' - { pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5); + { pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5, 0); } /* This rule handles instantiations of modules and user defined @@ -1476,7 +1530,6 @@ module_item { pform_set_attrib($3, $5, $7); delete $3; delete $5; - delete $7; } | KK_attribute '(' error ')' ';' { yyerror(@1, "error: Misformed $attribute parameter list."); } @@ -1646,14 +1699,14 @@ parameter_value_opt parameter_value_byname : '.' IDENTIFIER '(' expression ')' - { portname_t*tmp = new portname_t; + { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = $2; tmp->parm = $4; free($2); $$ = tmp; } | '.' IDENTIFIER '(' ')' - { portname_t*tmp = new portname_t; + { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = $2; tmp->parm = 0; free($2); @@ -1663,12 +1716,13 @@ parameter_value_byname parameter_value_byname_list : parameter_value_byname - { svector*tmp = new svector(1); + { svector*tmp = new svector(1); (*tmp)[0] = $1; $$ = tmp; } | parameter_value_byname_list ',' parameter_value_byname - { svector*tmp = new svector(*$1,$3); + { svector*tmp = + new svector(*$1,$3); delete $1; $$ = tmp; } @@ -1822,7 +1876,7 @@ port_reference_list port_name : '.' IDENTIFIER '(' expression ')' - { portname_t*tmp = new portname_t; + { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = $2; tmp->parm = $4; delete $2; @@ -1830,14 +1884,14 @@ port_name } | '.' IDENTIFIER '(' error ')' { yyerror(@4, "error: invalid port connection expression."); - portname_t*tmp = new portname_t; + named_pexpr_t*tmp = new named_pexpr_t; tmp->name = $2; tmp->parm = 0; delete $2; $$ = tmp; } | '.' IDENTIFIER '(' ')' - { portname_t*tmp = new portname_t; + { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = $2; tmp->parm = 0; delete $2; @@ -1847,13 +1901,13 @@ port_name port_name_list : port_name_list ',' port_name - { svector*tmp; - tmp = new svector(*$1, $3); + { svector*tmp; + tmp = new svector(*$1, $3); delete $1; $$ = tmp; } | port_name - { svector*tmp = new svector(1); + { svector*tmp = new svector(1); (*tmp)[0] = $1; $$ = tmp; } diff --git a/pform.cc b/pform.cc index 5361de299..d7c324415 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.cc,v 1.95 2002/05/20 02:06:01 steve Exp $" +#ident "$Id: pform.cc,v 1.96 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -555,7 +555,8 @@ void pform_make_events(list*names, const char*fn, unsigned ln) void pform_makegate(PGBuiltin::Type type, struct str_pair_t str, svector* delay, - const lgate&info) + const lgate&info, + svector*attr) { if (info.parms_by_name) { cerr << info.file << ":" << info.lineno << ": Gates do not " @@ -568,6 +569,13 @@ void pform_makegate(PGBuiltin::Type type, if (info.range[0]) cur->set_range(info.range[0], info.range[1]); + if (attr) { + for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { + named_pexpr_t*tmp = (*attr)[idx]; + cur->attributes[tmp->name] = tmp->parm; + } + } + cur->strength0(str.str0); cur->strength1(str.str1); cur->set_file(info.file); @@ -579,10 +587,19 @@ void pform_makegate(PGBuiltin::Type type, void pform_makegates(PGBuiltin::Type type, struct str_pair_t str, svector*delay, - svector*gates) + svector*gates, + svector*attr) { for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) { - pform_makegate(type, str, delay, (*gates)[idx]); + pform_makegate(type, str, delay, (*gates)[idx], attr); + } + + if (attr) { + for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { + named_pexpr_t*cur = (*attr)[idx]; + delete cur; + } + delete attr; } delete gates; @@ -611,7 +628,7 @@ static void pform_make_modgate(const char*type, named*byname = new named[cnt]; for (unsigned idx = 0 ; idx < cnt ; idx += 1) { - portname_t*curp = (*overrides->by_name)[idx]; + named_pexpr_t*curp = (*overrides->by_name)[idx]; byname[idx].name = curp->name; byname[idx].parm = curp->parm; } @@ -628,14 +645,14 @@ static void pform_make_modgate(const char*type, static void pform_make_modgate(const char*type, const string&name, struct parmvalue_t*overrides, - svector*bind, + svector*bind, PExpr*msb, PExpr*lsb, const char*fn, unsigned ln) { unsigned npins = bind->count(); named*pins = new named[npins]; for (unsigned idx = 0 ; idx < npins ; idx += 1) { - portname_t*curp = (*bind)[idx]; + named_pexpr_t*curp = (*bind)[idx]; pins[idx].name = curp->name; pins[idx].parm = curp->parm; } @@ -650,7 +667,7 @@ static void pform_make_modgate(const char*type, named*byname = new named[cnt]; for (unsigned idx = 0 ; idx < cnt ; idx += 1) { - portname_t*curp = (*overrides->by_name)[idx]; + named_pexpr_t*curp = (*overrides->by_name)[idx]; byname[idx].name = curp->name; byname[idx].parm = curp->parm; } @@ -1094,17 +1111,18 @@ void pform_set_function(const char*name, NetNet::Type ntype, pform_cur_module->add_function(name, func); } -void pform_set_attrib(const char*name, const string&key, const string&value) +void pform_set_attrib(const char*name, const string&key, char*value) { hname_t path (name); if (PWire*cur = pform_cur_module->get_wire(path)) { - cur->attributes[key] = value; + cur->attributes[key] = new PEString(value); } else if (PGate*cur = pform_cur_module->get_gate(name)) { - cur->attributes[key] = value; + cur->attributes[key] = new PEString(value); } else { + free(value); VLerror("Unable to match name for setting attribute."); } @@ -1115,15 +1133,16 @@ void pform_set_attrib(const char*name, const string&key, const string&value) * that this applies to every instantiation of the given type. */ void pform_set_type_attrib(const string&name, const string&key, - const string&value) + char*value) { map::const_iterator udp = pform_primitives.find(name); if (udp == pform_primitives.end()) { VLerror("type name is not (yet) defined."); + free(value); return; } - (*udp).second ->attributes[key] = value; + (*udp).second ->attributes[key] = new PEString(value); } /* @@ -1308,6 +1327,14 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.96 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.95 2002/05/20 02:06:01 steve * Add ranges and signed to port list declarations. * diff --git a/pform.h b/pform.h index b9289a4ee..ddd9a9ed8 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.h,v 1.57 2002/05/20 02:06:01 steve Exp $" +#ident "$Id: pform.h,v 1.58 2002/05/23 03:08:51 steve Exp $" #endif # include "netlist.h" @@ -77,11 +77,11 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max); /* This is information about port name information for named port connections. */ -typedef struct named portname_t; +typedef struct named named_pexpr_t; struct parmvalue_t { svector*by_order; - svector*by_name; + svector*by_name; }; struct str_pair_t { PGate::strength_t str0, str1; }; @@ -102,7 +102,7 @@ struct lgate { string name; svector*parms; - svector*parms_by_name; + svector*parms_by_name; PExpr*range[2]; @@ -184,10 +184,16 @@ extern void pform_set_reg_time(list*names); extern void pform_set_task(const string&, PTask*); extern void pform_set_function(const char*, NetNet::Type, svector*, PFunction*); + + /* pform_set_attrib and pform_set_type_attrib exist to support the + $attribute syntax, which can only set string values to + attributes. The functions keep the value strings that are + passed in. */ extern void pform_set_attrib(const char*name, const string&key, - const string&value); + char*value); extern void pform_set_type_attrib(const string&name, const string&key, - const string&value); + char*value); + extern void pform_set_parameter(const string&name, PExpr*expr); extern void pform_set_localparam(const string&name, PExpr*expr); extern void pform_set_defparam(const hname_t&name, PExpr*expr); @@ -207,7 +213,8 @@ extern void pform_make_events(list*names, extern void pform_makegates(PGBuiltin::Type type, struct str_pair_t str, svector*delay, - svector*gates); + svector*gates, + svector*attr); extern void pform_make_modgates(const char*type, struct parmvalue_t*overrides, @@ -241,6 +248,14 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.58 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.57 2002/05/20 02:06:01 steve * Add ranges and signed to port list declarations. * diff --git a/pform_dump.cc b/pform_dump.cc index 12345282a..c99077e06 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform_dump.cc,v 1.71 2002/05/19 23:37:28 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.72 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -251,11 +251,11 @@ void PWire::dump(ostream&out) const } out << ";" << endl; - for (map::const_iterator idx = attributes.begin() + for (map::const_iterator idx = attributes.begin() ; idx != attributes.end() ; idx ++) { out << " " << (*idx).first << " = \"" << - (*idx).second << "\"" << endl; + *(*idx).second << "\"" << endl; } } @@ -813,17 +813,25 @@ void PUdp::dump(ostream&out) const // Dump the attributes for the primitive as attribute // statements. - for (map::const_iterator idx = attributes.begin() + for (map::const_iterator idx = attributes.begin() ; idx != attributes.end() ; idx ++) { out << "$attribute(" << name_ << ", \"" << (*idx).first << - "\", \"" << (*idx).second << "\")" << endl; + "\", \"" << *(*idx).second << "\")" << endl; } } /* * $Log: pform_dump.cc,v $ + * Revision 1.72 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.71 2002/05/19 23:37:28 steve * Parse port_declaration_lists from the 2001 Standard. * diff --git a/syn-rules.y b/syn-rules.y index 36ecac35e..8034b8841 100644 --- a/syn-rules.y +++ b/syn-rules.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: syn-rules.y,v 1.17 2001/11/30 01:22:21 steve Exp $" +#ident "$Id: syn-rules.y,v 1.18 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -156,9 +156,9 @@ static void hookup_DFF_CE(NetFF*ff, NetESignal*d, NetEvProbe*pclk, connect(ff->pin_Clock(), pclk->pin(0)); if (ce) connect(ff->pin_Enable(), ce->pin(0)); - ff->attribute("LPM_FFType", "DFF"); + ff->attribute("LPM_FFType", verinum("DFF")); if (pclk->edge() == NetEvProbe::NEGEDGE) - ff->attribute("Clock:LPM_Polarity", "INVERT"); + ff->attribute("Clock:LPM_Polarity", verinum("INVERT")); } diff --git a/t-dll-api.cc b/t-dll-api.cc index 55a6ba433..f2ad97a9b 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-api.cc,v 1.77 2002/03/17 19:30:47 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.78 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -434,15 +434,29 @@ extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key) assert(net); unsigned idx; - for (idx = 0 ; idx < net->nattr_ ; idx += 1) { + for (idx = 0 ; idx < net->nattr ; idx += 1) { - if (strcmp(net->akey_[idx], key) == 0) - return net->aval_[idx]; + if (strcmp(net->attr[idx].key, key) == 0) + return net->attr[idx].type == IVL_ATT_STR + ? net->attr[idx].val.str + : 0; } return 0; } +extern "C" unsigned ivl_logic_attr_cnt(ivl_net_logic_t net) +{ + return net->nattr; +} + +extern "C" ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, + unsigned idx) +{ + assert(idx < net->nattr); + return net->attr + idx; +} + extern "C" const char* ivl_logic_name(ivl_net_logic_t net) { assert(net); @@ -1495,6 +1509,14 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.78 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.77 2002/03/17 19:30:47 steve * Add API to support user defined function. * diff --git a/t-dll.cc b/t-dll.cc index 638f63cf9..d90b32376 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.cc,v 1.81 2002/04/22 03:15:25 steve Exp $" +#ident "$Id: t-dll.cc,v 1.82 2002/05/23 03:08:51 steve Exp $" #endif # include "config.h" @@ -475,19 +475,29 @@ int dll_target::end_design(const Design*) static void logic_attributes(struct ivl_net_logic_s *obj, const NetNode*net) { - obj->nattr_ = net->nattr(); - if (obj->nattr_ > 0) { - obj->akey_ = (char**)calloc(obj->nattr_, sizeof(char*)); - obj->aval_ = (char**)calloc(obj->nattr_, sizeof(char*)); + obj->nattr = net->nattr(); + if (obj->nattr > 0) { + obj->attr = new struct ivl_attribute_s[obj->nattr]; + for (unsigned idx = 0 ; idx < obj->nattr ; idx += 1) { + verinum tmp = net->attr_value(idx); + obj->attr[idx].key = strdup(net->attr_key(idx)); + if (tmp.is_string()) { + obj->attr[idx].type = IVL_ATT_STR; + obj->attr[idx].val.str = + strdup(tmp.as_string().c_str()); - for (unsigned idx = 0 ; idx < obj->nattr_ ; idx += 1) { - obj->akey_[idx] = strdup(net->attr_key(idx)); - obj->aval_[idx] = strdup(net->attr_value(idx)); + } else if (tmp == verinum()) { + obj->attr[idx].type = IVL_ATT_VOID; + + } else { + obj->attr[idx].type = IVL_ATT_NUM; + obj->attr[idx].val.num = tmp.as_long(); + } } + } else { - obj->akey_ = 0; - obj->aval_ = 0; + obj->attr = 0; } } @@ -930,7 +940,7 @@ void dll_target::memory(const NetMemory*net) void dll_target::lpm_add_sub(const NetAddSub*net) { ivl_lpm_t obj = new struct ivl_lpm_s; - if (net->attribute("LPM_Direction") == "SUB") + if (net->attribute("LPM_Direction") == verinum("SUB")) obj->type = IVL_LPM_SUB; else obj->type = IVL_LPM_ADD; @@ -1881,7 +1891,7 @@ void dll_target::signal(const NetNet*net) obj->aval_ = new char*[obj->nattr_]; for (unsigned idx = 0 ; idx < obj->nattr_ ; idx += 1) { obj->akey_[idx] = strdup(net->attr_key(idx)); - obj->aval_[idx] = strdup(net->attr_value(idx)); + obj->aval_[idx] = strdup(net->attr_value(idx).as_string().c_str()); } /* Get the nexus objects for all the pins of the signal. If @@ -1933,6 +1943,14 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.82 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.81 2002/04/22 03:15:25 steve * Keep delays applied to BUFZ devices. * diff --git a/t-dll.h b/t-dll.h index a2d6161a0..eddda5545 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.76 2002/03/09 02:10:22 steve Exp $" +#ident "$Id: t-dll.h,v 1.77 2002/05/23 03:08:51 steve Exp $" #endif # include "target.h" @@ -368,9 +368,8 @@ struct ivl_net_logic_s { unsigned npins_; ivl_nexus_t*pins_; - char**akey_; - char**aval_; - unsigned nattr_; + struct ivl_attribute_s*attr; + unsigned nattr; unsigned delay[3]; }; @@ -599,6 +598,14 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.77 2002/05/23 03:08:51 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.76 2002/03/09 02:10:22 steve * Add the NetUserFunc netlist node. * diff --git a/t-xnf.cc b/t-xnf.cc index 626fef2e6..5d7307493 100644 --- a/t-xnf.cc +++ b/t-xnf.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-xnf.cc,v 1.43 2001/07/25 03:10:50 steve Exp $" +#ident "$Id: t-xnf.cc,v 1.44 2002/05/23 03:08:52 steve Exp $" #endif # include "config.h" @@ -340,7 +340,7 @@ void target_xnf::signal(const NetNet*net) /* Now look to see if a PAD attribute is attached, and if so write out PAD information to the XNF and the ncf files. */ - string pad = net->attribute("PAD"); + string pad = net->attribute("PAD").as_string(); if (pad == "") return; @@ -672,19 +672,19 @@ void target_xnf::lpm_compare_le_(ostream&os, const NetCompare*dev) void target_xnf::lpm_ff(const NetFF*net) { - string type = net->attribute("LPM_FFType"); + string type = net->attribute("LPM_FFType").as_string(); if (type == "") type = "DFF"; // XXXX For now, only support DFF assert(type == "DFF"); - string lcaname = net->attribute("XNF-LCA"); + string lcaname = net->attribute("XNF-LCA").as_string(); if (lcaname != "") { draw_sym_with_lcaname(out_, lcaname, net); return; } - assert(net->attribute("XNF-LCA") == ""); + assert(net->attribute("XNF-LCA") == verinum("")); /* Create a DFF object for each bit of width. The symbol name has the index number appended so that read XNF may be able @@ -711,7 +711,7 @@ void target_xnf::lpm_ff(const NetFF*net) draw_pin(out_, "Q", net->pin_Q(idx)); draw_pin(out_, "D", net->pin_Data(idx)); - if (net->attribute("Clock:LPM_Polarity") == "INVERT") + if (net->attribute("Clock:LPM_Polarity") == verinum("INVERT")) draw_pin(out_, "~C", net->pin_Clock()); else draw_pin(out_, "C", net->pin_Clock()); @@ -811,7 +811,7 @@ void target_xnf::logic(const NetLogic*net) { // The XNF-LCA attribute overrides anything I might guess // about this object. - string lca = net->attribute("XNF-LCA"); + string lca = net->attribute("XNF-LCA").as_string(); if (lca != "") { draw_sym_with_lcaname(out_, lca, net); return; @@ -909,7 +909,7 @@ bool target_xnf::bufz(const NetBUFZ*net) void target_xnf::udp(const NetUDP*net) { - string lca = net->attribute("XNF-LCA"); + string lca = net->attribute("XNF-LCA").as_string(); // I only know how to draw a UDP if it has the XNF-LCA // attribute attached to it. @@ -927,6 +927,14 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj }; /* * $Log: t-xnf.cc,v $ + * Revision 1.44 2002/05/23 03:08:52 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.43 2001/07/25 03:10:50 steve * Create a config.h.in file to hold all the config * junk, and support gcc 3.0. (Stephan Boettcher) diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 1ecd4fd00..32675e0b5 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: stub.c,v 1.57 2002/04/27 04:20:52 steve Exp $" +#ident "$Id: stub.c,v 1.58 2002/05/23 03:08:52 steve Exp $" #endif # include "config.h" @@ -556,6 +556,22 @@ static void show_logic(ivl_net_logic_t net) fprintf(out, ", %s", ivl_nexus_name(ivl_logic_pin(net,idx))); fprintf(out, ");\n"); + + npins = ivl_logic_attr_cnt(net); + for (idx = 0 ; idx < npins ; idx += 1) { + ivl_attribute_t cur = ivl_logic_attr_val(net,idx); + switch (cur->type) { + case IVL_ATT_VOID: + fprintf(out, " %s\n", cur->key); + break; + case IVL_ATT_NUM: + fprintf(out, " %s = %ld\n", cur->key, cur->val.num); + break; + case IVL_ATT_STR: + fprintf(out, " %s = %s\n", cur->key, cur->val.str); + break; + } + } } static int show_scope(ivl_scope_t net, void*x) @@ -630,6 +646,14 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.58 2002/05/23 03:08:52 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.57 2002/04/27 04:20:52 steve * Dump parametres for system functions. * diff --git a/util.h b/util.h index 89bf1e502..dafbfc331 100644 --- a/util.h +++ b/util.h @@ -19,9 +19,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: util.h,v 1.4 2001/12/03 04:47:15 steve Exp $" +#ident "$Id: util.h,v 1.5 2002/05/23 03:08:52 steve Exp $" #endif +# include +# include +# include "verinum.h" + +class PExpr; +class Design; +class NetScope; /* * This file attempts to locate a module in a file. It operates by @@ -31,8 +38,27 @@ extern bool load_module(const char*type); + +struct attrib_list_t { + string key; + verinum val; +}; + +extern attrib_list_t* evaluate_attributes(const map&att, + unsigned&natt, + const Design*des, + const NetScope*scope); + /* * $Log: util.h,v $ + * Revision 1.5 2002/05/23 03:08:52 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.4 2001/12/03 04:47:15 steve * Parser and pform use hierarchical names as hname_t * objects instead of encoded strings. diff --git a/xnfio.cc b/xnfio.cc index ef15d4fa4..1c0d2f75f 100644 --- a/xnfio.cc +++ b/xnfio.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: xnfio.cc,v 1.19 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: xnfio.cc,v 1.20 2002/05/23 03:08:52 steve Exp $" #endif # include "config.h" @@ -41,7 +41,7 @@ class xnfio_f : public functor_t { static bool is_a_pad(const NetNet*net) { - if (net->attribute("PAD") == "") + if (net->attribute("PAD") == verinum()) return false; return true; @@ -90,7 +90,7 @@ static NetLogic* make_obuf(Design*des, NetNet*net) && (count_inputs(tmp->pin(0)) == 0) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { - tmp->attribute("XNF-LCA", "OBUF:O,I"); + tmp->attribute("XNF-LCA", verinum("OBUF:O,I")); return tmp; } @@ -103,7 +103,7 @@ static NetLogic* make_obuf(Design*des, NetNet*net) && (count_inputs(tmp->pin(0)) == 0) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { - tmp->attribute("XNF-LCA", "OBUF:O,~I"); + tmp->attribute("XNF-LCA", verinum("OBUF:O,~I")); return tmp; } @@ -115,7 +115,7 @@ static NetLogic* make_obuf(Design*des, NetNet*net) && (count_inputs(tmp->pin(0)) == 0) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { - tmp->attribute("XNF-LCA", "OBUFT:O,I,~T"); + tmp->attribute("XNF-LCA", verinum("OBUFT:O,I,~T")); return tmp; } @@ -123,7 +123,7 @@ static NetLogic* make_obuf(Design*des, NetNet*net) && (count_inputs(tmp->pin(0)) == 0) && (count_outputs(tmp->pin(0)) == 1) && (idx->get_pin() == 0) ) { - tmp->attribute("XNF-LCA", "OBUFT:O,I,T"); + tmp->attribute("XNF-LCA", verinum("OBUFT:O,I,T")); return tmp; } } @@ -134,9 +134,7 @@ static NetLogic* make_obuf(Design*des, NetNet*net) 2, NetLogic::BUF); des->add_node(buf); - mapattr; - attr["XNF-LCA"] = "OBUF:O,I"; - buf->set_attributes(attr); + buf->attribute("XNF-LCA", verinum("OBUF:O,I")); // Put the buffer between this signal and the rest of the // netlist. @@ -178,7 +176,7 @@ static void absorb_OFF(Design*des, NetLogic*buf) return; if (ff->width() != 1) return; - if (ff->attribute("LPM_FFType") != "DFF") + if (ff->attribute("LPM_FFType") != verinum("DFF")) return; /* Connect the flip-flop output to the buffer output and @@ -192,7 +190,7 @@ static void absorb_OFF(Design*des, NetLogic*buf) for (unsigned idx = 0 ; idx < ff->pin_count() ; idx += 1) names[idx] = ""; - if (ff->attribute("Clock:LPM_Polarity") == "INVERT") + if (ff->attribute("Clock:LPM_Polarity") == verinum("INVERT")) names[ff->pin_Clock().get_pin()] = "~C"; else names[ff->pin_Clock().get_pin()] = "C"; @@ -227,7 +225,7 @@ static void make_ibuf(Design*des, NetNet*net) if ((tmp = dynamic_cast(idx->get_obj())) == 0) continue; - if (tmp->attribute("XNF-LCA") != "") + if (tmp->attribute("XNF-LCA") != verinum()) continue; // Found a BUF, it is only useable if the only input is @@ -235,7 +233,7 @@ static void make_ibuf(Design*des, NetNet*net) if ((tmp->type() == NetLogic::BUF) && (count_inputs(tmp->pin(1)) == 1) && (count_outputs(tmp->pin(1)) == 0)) { - tmp->attribute("XNF-LCA", "IBUF:O,I"); + tmp->attribute("XNF-LCA", verinum("IBUF:O,I")); return; } @@ -246,9 +244,7 @@ static void make_ibuf(Design*des, NetNet*net) 2, NetLogic::BUF); des->add_node(buf); - mapattr; - attr["XNF-LCA"] = "IBUF:O,I"; - buf->set_attributes(attr); + buf->attribute("XNF-LCA", verinum("IBUF:O,I")); // Put the buffer between this signal and the rest of the // netlist. @@ -274,7 +270,7 @@ void xnfio_f::signal(Design*des, NetNet*net) return; assert(net->pin_count() == 1); - string pattr = net->attribute("PAD"); + string pattr = net->attribute("PAD").as_string(); switch (pattr[0]) { case 'i': @@ -367,6 +363,14 @@ void xnfio(Design*des) /* * $Log: xnfio.cc,v $ + * Revision 1.20 2002/05/23 03:08:52 steve + * Add language support for Verilog-2001 attribute + * syntax. Hook this support into existing $attribute + * handling, and add number and void value types. + * + * Add to the ivl_target API new functions for access + * of complex attributes attached to gates. + * * Revision 1.19 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. *