diff --git a/PExpr.h b/PExpr.h index 888f22a55..8298e1012 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.68 2005/01/09 20:16:00 steve Exp $" +#ident "$Id: PExpr.h,v 1.69 2005/07/07 16:22:49 steve Exp $" #endif # include @@ -198,6 +198,14 @@ class PEFNumber : public PExpr { bool sys_task_arg =false) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; + virtual NetNet* elaborate_net(Design*des, NetScope*scope, + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay, + Link::strength_t drive0, + Link::strength_t drive1) const; + virtual void dump(ostream&) const; private: @@ -506,6 +514,9 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.69 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.68 2005/01/09 20:16:00 steve * Use PartSelect/PV and VP to handle part selects through ports. * diff --git a/PWire.cc b/PWire.cc index dceedb770..e7e8e9fef 100644 --- a/PWire.cc +++ b/PWire.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2005 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 @@ -17,15 +17,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $" +#ident "$Id: PWire.cc,v 1.11 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" # include "PWire.h" # include -PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt) -: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false), +PWire::PWire(const hname_t&n, + NetNet::Type t, + NetNet::PortType pt, + ivl_variable_type_t dt) +: hname_(n), type_(t), port_type_(pt), data_type_(dt), + signed_(false), isint_(false), lidx_(0), ridx_(0) { if (t == NetNet::INTEGER) { @@ -35,8 +39,12 @@ lidx_(0), ridx_(0) } } -PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt) -: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false), +PWire::PWire(char*n, + NetNet::Type t, + NetNet::PortType pt, + ivl_variable_type_t dt) +: hname_(n), type_(t), port_type_(pt), data_type_(dt), + signed_(false), isint_(false), lidx_(0), ridx_(0) { if (t == NetNet::INTEGER) { @@ -108,6 +116,19 @@ bool PWire::set_port_type(NetNet::PortType pt) } } +bool PWire::set_data_type(ivl_variable_type_t dt) +{ + if (data_type_ != IVL_VT_NO_TYPE) + if (data_type_ != dt) + return false; + else + return true; + + assert(data_type_ == IVL_VT_NO_TYPE); + data_type_ = dt; + return true; +} + void PWire::set_signed(bool flag) { signed_ = flag; @@ -140,6 +161,9 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx) /* * $Log: PWire.cc,v $ + * Revision 1.11 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.10 2002/08/12 01:34:58 steve * conditional ident string using autoconfig. * diff --git a/PWire.h b/PWire.h index 350c08047..398fe1f09 100644 --- a/PWire.h +++ b/PWire.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PWire.h,v 1.17 2004/02/20 18:53:33 steve Exp $" +#ident "$Id: PWire.h,v 1.18 2005/07/07 16:22:49 steve Exp $" #endif # include "netlist.h" @@ -49,8 +49,14 @@ class Design; class PWire : public LineInfo { public: - PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt); - PWire(char*name, NetNet::Type t, NetNet::PortType pt); + PWire(const hname_t&hname, + NetNet::Type t, + NetNet::PortType pt, + ivl_variable_type_t dt); + PWire(char*name, + NetNet::Type t, + NetNet::PortType pt, + ivl_variable_type_t dt); // Return a hierarchical name. const hname_t&path() const; @@ -65,6 +71,9 @@ class PWire : public LineInfo { bool get_signed() const; bool get_isint() const; + bool set_data_type(ivl_variable_type_t dt); + ivl_variable_type_t get_data_type() const; + void set_range(PExpr*msb, PExpr*lsb); void set_memory_idx(PExpr*ldx, PExpr*rdx); @@ -80,6 +89,7 @@ class PWire : public LineInfo { hname_t hname_; NetNet::Type type_; NetNet::PortType port_type_; + ivl_variable_type_t data_type_; bool signed_; bool isint_; // original type of integer @@ -100,6 +110,9 @@ class PWire : public LineInfo { /* * $Log: PWire.h,v $ + * Revision 1.18 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.17 2004/02/20 18:53:33 steve * Addtrbute keys are perm_strings. * diff --git a/README.txt b/README.txt index cdcc2803e..1b3974654 100644 --- a/README.txt +++ b/README.txt @@ -470,6 +470,20 @@ language that are defined. combinational always blocks to be triggered when the values in the sensitivity list are initialized by initial threads. + Nets with Types + + Icarus Verilog support an extension syntax that allows nets + and regs to be explicitly typed. The currently supported types + are logic, bool and real. This implies that "logic" and "bool" + are new keywords. Typical syntax is: + + wire real foo = 1.0; + reg logic bar, bat; + + ... and so forth. The syntax can be turned off by using the + -g2 flag to iverilog, and turned on explicitly with the -g2x + flag to iverilog. + 6.0 CREDITS Except where otherwise noted, Icarus Verilog, ivl and ivlpp are diff --git a/compiler.h b/compiler.h index 37e527455..2b8f054f2 100644 --- a/compiler.h +++ b/compiler.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: compiler.h,v 1.28 2005/06/28 04:25:55 steve Exp $" +#ident "$Id: compiler.h,v 1.29 2005/07/07 16:22:49 steve Exp $" #endif # include @@ -94,7 +94,8 @@ extern listlibrary_suff; extern int build_library_index(const char*path, bool key_case_sensitive); /* This is the generation of Verilog that the compiler is asked to - support. */ + support. Then there are also more detailed controls for more + specific language features. */ enum generation_t { GN_VER1995 = 1, GN_VER2001 = 2, @@ -103,6 +104,11 @@ enum generation_t { }; extern generation_t generation_flag; +extern bool gn_cadence_types_flag; + +/* These functions test that specific features are enabled. */ +inline bool gn_cadence_types_enabled() +{ return gn_cadence_types_flag && generation_flag==GN_VER2001X; } /* This is the string to use to invoke the preprocessor. */ extern char*ivlpp_string; @@ -137,6 +143,9 @@ extern int load_sys_func_table(const char*path); /* * $Log: compiler.h,v $ + * Revision 1.29 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.28 2005/06/28 04:25:55 steve * Remove reference to SystemVerilog. * diff --git a/design_dump.cc b/design_dump.cc index a28a87042..f161e9655 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: design_dump.cc,v 1.160 2005/05/24 01:44:27 steve Exp $" +#ident "$Id: design_dump.cc,v 1.161 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -68,6 +68,28 @@ ostream& operator << (ostream&o, Link::strength_t str) return o; } +ostream& operator << (ostream&o, ivl_variable_type_t val) +{ + switch (val) { + case IVL_VT_VOID: + o << "void"; + break; + case IVL_VT_NO_TYPE: + o << ""; + break; + case IVL_VT_REAL: + o << "real"; + break; + case IVL_VT_BOOL: + o << "bool"; + break; + case IVL_VT_LOGIC: + o << "logic"; + break; + } + return o; +} + /* Dump a net. This can be a wire or register. */ void NetNet::dump_net(ostream&o, unsigned ind) const { @@ -75,6 +97,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const pin_count() << "]"; if (local_flag_) o << " (local)"; + o << " " << data_type_; if (signed_) o << " signed"; switch (port_type_) { @@ -276,6 +299,13 @@ void NetFF::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetLiteral::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "constant real " << real_ + << ": " << name() << endl; + dump_node_pins(o, ind+4); +} + void NetLogic::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "logic: "; @@ -1151,6 +1181,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.161 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.160 2005/05/24 01:44:27 steve * Do sign extension of structuran nets. * diff --git a/elab_net.cc b/elab_net.cc index befe21ddf..e6b71463f 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_net.cc,v 1.165 2005/05/24 01:44:27 steve Exp $" +#ident "$Id: elab_net.cc,v 1.166 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -182,9 +182,9 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope, NetNet*osig; - unsigned width = lsig->pin_count(); - if (rsig->pin_count() > lsig->pin_count()) - width = rsig->pin_count(); + unsigned width = lsig->vector_width(); + if (rsig->vector_width() > lsig->vector_width()) + width = rsig->vector_width(); /* The owidth is the output width of the lpm_add_sub @@ -212,15 +212,26 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope, // Pad out the operands, if necessary, the match the width of // the adder device. - if (lsig->pin_count() < width) + if (lsig->vector_width() < width) lsig = pad_to_width(des, lsig, width); - if (rsig->pin_count() < width) + if (rsig->vector_width() < width) rsig = pad_to_width(des, rsig, width); + // Check that the argument types match. + if (lsig->data_type() != rsig->data_type()) { + cerr << get_line() << ": error: Arguments of add/sub " + << "have different data types." << endl; + cerr << get_line() << ": : Left argument is " + << lsig->data_type() << ", right argument is " + << rsig->data_type() << "." << endl; + des->errors += 1; + } + // Make the adder as wide as the widest operand osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, owidth); + osig->data_type(lsig->data_type()); osig->local_flag(true); if (debug_elaborate) { cerr << get_line() << ": debug: Elaborate NetAddSub " @@ -416,6 +427,7 @@ static NetNet* compare_eq_constant(Design*des, NetScope*scope, NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 0, 0); + tmp->data_type(IVL_VT_LOGIC); tmp->local_flag(true); tmp->set_line(*lsig); @@ -545,6 +557,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE); + osig->data_type(IVL_VT_LOGIC); osig->set_line(*this); osig->local_flag(true); @@ -698,6 +711,18 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope, rwidth = rsig->vector_width(); } + /* The arguments of a divide must have the same type. */ + if (lsig->data_type() != rsig->data_type()) { + cerr << get_line() << ": error: Arguments of divide " + << "have different data types." << endl; + cerr << get_line() << ": : Left argument is " + << lsig->data_type() << ", right argument is " + << rsig->data_type() << "." << endl; + des->errors += 1; + } + + ivl_variable_type_t data_type = lsig->data_type(); + // Create a device with the calculated dimensions. NetDivide*div = new NetDivide(scope, scope->local_symbol(), rwidth, lsig->vector_width(), @@ -721,6 +746,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, lwidth); osig->local_flag(true); + osig->data_type(data_type); osig->set_signed(div->get_signed()); connect(div->pin_Result(), osig->pin(0)); @@ -743,6 +769,18 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope, NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0); if (rsig == 0) return 0; + /* The arguments of a modulus must have the same type. */ + if (lsig->data_type() != rsig->data_type()) { + cerr << get_line() << ": error: Arguments of modulus " + << "have different data types." << endl; + cerr << get_line() << ": : Left argument is " + << lsig->data_type() << ", right argument is " + << rsig->data_type() << "." << endl; + des->errors += 1; + } + + ivl_variable_type_t data_type = lsig->data_type(); + /* rwidth is result width. */ unsigned rwidth = lwidth; if (rwidth == 0) { @@ -763,11 +801,9 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, rwidth); + osig->data_type(data_type); osig->local_flag(true); - unsigned cnt = osig->pin_count(); - if (cnt > rwidth) cnt = rwidth; - connect(mod->pin_Result(), osig->pin(0)); return osig; @@ -904,6 +940,18 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope, // The mult is signed if both its operands are signed. bool arith_is_signed = lsig->get_signed() && rsig->get_signed(); + /* The arguments of a divide must have the same type. */ + if (lsig->data_type() != rsig->data_type()) { + cerr << get_line() << ": error: Arguments of multiply " + << "have different data types." << endl; + cerr << get_line() << ": : Left argument is " + << lsig->data_type() << ", right argument is " + << rsig->data_type() << "." << endl; + des->errors += 1; + } + + ivl_variable_type_t data_type = lsig->data_type(); + unsigned rwidth = lwidth; if (rwidth == 0) { rwidth = lsig->vector_width() + rsig->vector_width(); @@ -929,6 +977,7 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope, // Make a signal to carry the output from the multiply. NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, rwidth); + osig->data_type(data_type); osig->local_flag(true); connect(mult->pin_Result(), osig->pin(0)); @@ -949,6 +998,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, bool right_flag = op_ == 'r' || op_ == 'R'; bool signed_flag = op_ == 'R'; + ivl_variable_type_t data_type = lsig->data_type(); /* Handle the special case of a constant shift amount. There is no reason in this case to create a gate at all, just @@ -975,6 +1025,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, result that I return from this function. */ NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, lwidth); + osig->data_type( data_type ); osig->local_flag(true); @@ -1003,6 +1054,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, NetNet*zero = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, pad_width); + zero->data_type( data_type ); zero->local_flag(true); zero->set_line(*this); @@ -1017,6 +1069,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, des->add_node(sign_pad); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1); + tmp->data_type( data_type ); connect(sign_bit->pin(0), tmp->pin(0)); connect(sign_bit->pin(0), sign_pad->pin(1)); @@ -1066,6 +1119,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, input) */ NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, part_width); + tmp->data_type( data_type ); tmp->local_flag(true); tmp->set_line(*this); connect(part->pin(0), tmp->pin(0)); @@ -1091,6 +1145,7 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, lwidth); + osig->data_type( data_type ); osig->local_flag(true); osig->set_signed(signed_flag); @@ -1367,6 +1422,7 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, vector_width * repeat); + osig->data_type(IVL_VT_LOGIC); connect(dev->pin(0), osig->pin(0)); @@ -1399,8 +1455,6 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, /* Elaborate the selector. */ NetNet*sel; - unsigned sig_width = sig->vector_width(); - if (sig->msb() < sig->lsb()) { NetExpr*sel_expr = msb_->elaborate_expr(des, scope); sel_expr = make_sub_expr(sig->lsb(), sel_expr); @@ -1439,6 +1493,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, NetNet*out = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1); + out->data_type(sig->data_type()); connect(out->pin(0), mux->pin(0)); return out; @@ -1578,6 +1633,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, part_count-1, 0); + tmp->data_type( sig->data_type() ); tmp->local_flag(true); connect(tmp->pin(0), ps->pin(0)); @@ -1640,6 +1696,7 @@ NetNet* PEIdent::elaborate_net_ram_(Design*des, NetScope*scope, NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, ram->width()); + osig->data_type(IVL_VT_LOGIC); osig->local_flag(true); connect(ram->pin_Q(), osig->pin(0)); @@ -1737,6 +1794,34 @@ NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope, return osig; } +/* + * Elaborate a number as a NetConst object. + */ +NetNet* PEFNumber::elaborate_net(Design*des, NetScope*scope, + unsigned lwidth, + unsigned long rise, + unsigned long fall, + unsigned long decay, + Link::strength_t drive0, + Link::strength_t drive1) const +{ + if (debug_elaborate) { + cerr << get_line() << ": debug: Elaborate real literal node, " + << "value=" << value() << "." << endl; + } + + NetLiteral*obj = new NetLiteral(scope, scope->local_symbol(), value()); + obj->set_line(*this); + des->add_node(obj); + + NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, 1); + net->data_type(IVL_VT_REAL); + net->local_flag(true); + + connect(net->pin(0), obj->pin(0)); + return net; +} + /* * This private method evaluates the part selects (if any) for the * signal. The sig argument is the NetNet already located for the @@ -1995,6 +2080,8 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const /* * Elaborate a number as a NetConst object. + * + * The code assumes that the result is IVL_VT_LOGIC. */ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, unsigned lwidth, @@ -2007,10 +2094,14 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, /* If we are constrained by a l-value size, then just make a number constant with the correct size and set as many bits - in that constant as make sense. Pad excess with zeros. */ + in that constant as make sense. Pad excess with + zeros. Also, assume that numbers are meant to be logic + type. */ + if (lwidth > 0) { NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, lwidth); + net->data_type(IVL_VT_LOGIC); net->local_flag(true); net->set_signed(value_->has_sign()); @@ -2049,6 +2140,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, if (value_->has_len()) { NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, value_->len()); + net->data_type(IVL_VT_LOGIC); net->local_flag(true); net->set_signed(value_->has_sign()); NetConst*tmp = new NetConst(scope, scope->local_symbol(), @@ -2093,6 +2185,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, width); + net->data_type(IVL_VT_LOGIC); net->local_flag(true); NetConst*tmp = new NetConst(scope, scope->local_symbol(), num); connect(net->pin(0), tmp->pin(0)); @@ -2323,6 +2416,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, assert(width > 0); sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, width); + sig->data_type(IVL_VT_LOGIC); sig->local_flag(true); /* Take the 2s complement by taking the 1s complement @@ -2360,6 +2454,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, case '~': // Bitwise NOT sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sub_sig->vector_width()); + sig->data_type(sub_sig->data_type()); sig->local_flag(true); gate = new NetLogic(scope, scope->local_symbol(), 2, NetLogic::NOT, sub_sig->vector_width()); @@ -2390,6 +2485,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, case '-': // Unary 2's complement. sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, owidth); + sig->data_type(sub_sig->data_type()); sig->local_flag(true); if (sub_sig->vector_width() < owidth) @@ -2468,6 +2564,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.166 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.165 2005/05/24 01:44:27 steve * Do sign extension of structuran nets. * diff --git a/elab_sig.cc b/elab_sig.cc index c10f7c155..cf20769a3 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_sig.cc,v 1.38 2005/02/13 01:15:07 steve Exp $" +#ident "$Id: elab_sig.cc,v 1.39 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -651,6 +651,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const } NetNet*sig = new NetNet(scope, name, wtype, msb, lsb); + sig->data_type(data_type_); sig->set_line(*this); sig->port_type(port_type_); sig->set_signed(get_signed()); @@ -666,6 +667,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const /* * $Log: elab_sig.cc,v $ + * Revision 1.39 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.38 2005/02/13 01:15:07 steve * Replace supply nets with wires connected to pullup/down supply devices. * diff --git a/emit.cc b/emit.cc index d2197af6f..b639c6e53 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: emit.cc,v 1.84 2005/05/24 01:44:27 steve Exp $" +#ident "$Id: emit.cc,v 1.85 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -97,6 +97,11 @@ bool NetFF::emit_node(struct target_t*tgt) const return true; } +bool NetLiteral::emit_node(struct target_t*tgt) const +{ + return tgt->net_literal(this); +} + bool NetModulo::emit_node(struct target_t*tgt) const { tgt->lpm_modulo(this); @@ -528,6 +533,9 @@ int emit(const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.85 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.84 2005/05/24 01:44:27 steve * Do sign extension of structuran nets. * diff --git a/functor.cc b/functor.cc index 542292262..5394e90b7 100644 --- a/functor.cc +++ b/functor.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: functor.cc,v 1.34 2005/05/24 01:44:27 steve Exp $" +#ident "$Id: functor.cc,v 1.35 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -59,6 +59,10 @@ void functor_t::lpm_divide(class Design*, class NetDivide*) { } +void functor_t::lpm_literal(class Design*, class NetLiteral*) +{ +} + void functor_t::lpm_modulo(class Design*, class NetModulo*) { } @@ -194,6 +198,11 @@ void NetFF::functor_node(Design*des, functor_t*fun) fun->lpm_ff(des, this); } +void NetLiteral::functor_node(Design*des, functor_t*fun) +{ + fun->lpm_literal(des, this); +} + void NetLogic::functor_node(Design*des, functor_t*fun) { fun->lpm_logic(des, this); @@ -285,6 +294,9 @@ int proc_match_t::event_wait(NetEvWait*) /* * $Log: functor.cc,v $ + * Revision 1.35 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.34 2005/05/24 01:44:27 steve * Do sign extension of structuran nets. * diff --git a/functor.h b/functor.h index 2b7f4873f..83aed16b3 100644 --- a/functor.h +++ b/functor.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: functor.h,v 1.22 2005/05/24 01:44:27 steve Exp $" +#ident "$Id: functor.h,v 1.23 2005/07/07 16:22:49 steve Exp $" #endif /* @@ -63,6 +63,9 @@ struct functor_t { /* This method is called for each structural constant. */ virtual void lpm_divide(class Design*des, class NetDivide*); + /* Constant literals. */ + virtual void lpm_literal(class Design*des, class NetLiteral*); + /* This method is called for each structural constant. */ virtual void lpm_modulo(class Design*des, class NetModulo*); @@ -97,6 +100,9 @@ struct proc_match_t { /* * $Log: functor.h,v $ + * Revision 1.23 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.22 2005/05/24 01:44:27 steve * Do sign extension of structuran nets. * diff --git a/ivl_target.h b/ivl_target.h index eefede426..e476ca48c 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: ivl_target.h,v 1.156 2005/06/13 22:25:37 steve Exp $" +#ident "$Id: ivl_target.h,v 1.157 2005/07/07 16:22:49 steve Exp $" #endif #ifdef __cplusplus @@ -325,8 +325,11 @@ typedef enum ivl_statement_type_e { expression. */ typedef enum ivl_variable_type_e { IVL_VT_VOID = 0, /* Not used */ + IVL_VT_NO_TYPE, /* Place holder for missing/unknown type. */ IVL_VT_REAL, - IVL_VT_VECTOR + IVL_VT_BOOL, + IVL_VT_LOGIC, + IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */ } ivl_variable_type_t; /* This is the type of the function to apply to a process. */ @@ -407,12 +410,16 @@ extern int ivl_design_time_precision(ivl_design_t des); extern unsigned ivl_design_consts(ivl_design_t des); extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx); -/* VECTOR CONSTANTS - * Vector constants are nodes with no input and a single vector - * output. The output is an array of 4-value bits, using a single char +/* LITERAL CONSTANTS + * Literal constants are nodes with no input and a single constant + * output. The form of the output depends on the type of the node. + * The output is an array of 4-value bits, using a single char * value for each bit. The bits of the vector are in canonical (lsb * first) order for the width of the constant. * + * ivl_const_type + * The is the type of the node. + * * ivl_const_bits * This returns a pointer to an array of conststant characters, * each byte a '0', '1', 'x' or 'z'. The array is *not* nul @@ -427,14 +434,25 @@ extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx); * ivl_const_width * Return the width, in logical bits, of the constant. * - * ivl_const_pin - * ivl_const_pins - * DEPRECATED + * SEMANTIC NOTES + * + * The const_type of the literal constant must match the + * ivl_signal_data_type if the signals that share the nexus of this + * node. The compiler makes sure it is so, converting constant values + * as needed. + * + * - IVL_VT_LOGIC + * + * - IVL_VT_REAL + * Real valued constants have a width of 1. The value emitted to the + * output is ivl_const_real. */ +extern ivl_variable_type_t ivl_const_type(ivl_net_const_t net); extern const char* ivl_const_bits(ivl_net_const_t net); extern ivl_nexus_t ivl_const_nex(ivl_net_const_t net); extern int ivl_const_signed(ivl_net_const_t net); extern unsigned ivl_const_width(ivl_net_const_t net); +extern double ivl_const_real(ivl_net_const_t net); /* extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx); */ /* extern unsigned ivl_const_pins(ivl_net_const_t net); */ @@ -1398,6 +1416,11 @@ extern int ivl_scope_time_units(ivl_scope_t net); * ivl_signal_type * Return the type of the signal, i.e., reg, wire, tri0, etc. * + * ivl_signal_data_type + * Return the data type of the signal, i.e. logic, real, bool, + * etc. All the signals connected to a nexus should have the same + * data type + * * ivl_signal_name (DEPRECATED) * This function returns the fully scoped hierarchical name for the * signal. The name refers to the entire vector that is the signal. @@ -1430,6 +1453,7 @@ extern int ivl_signal_signed(ivl_signal_t net); extern int ivl_signal_integer(ivl_signal_t net); extern int ivl_signal_local(ivl_signal_t net); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); +extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); @@ -1667,6 +1691,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.157 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.156 2005/06/13 22:25:37 steve * Document ivl_logic_delay function. * diff --git a/lexor.lex b/lexor.lex index 0d762b0e3..629aeb265 100644 --- a/lexor.lex +++ b/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: lexor.lex,v 1.86 2004/06/13 04:56:54 steve Exp $" +#ident "$Id: lexor.lex,v 1.87 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -198,12 +198,27 @@ W [ \t\b\f\r]+ [a-zA-Z_][a-zA-Z0-9$_]* { int rc = lexor_keyword_code(yytext, yyleng); - if (rc == IDENTIFIER) { + switch (rc) { + case IDENTIFIER: yylval.text = strdup(yytext); if (strncmp(yylval.text,"PATHPULSE$", 10) == 0) rc = PATHPULSE_IDENTIFIER; - } else { + break; + + case K_bool: + case K_logic: + case K_wone: + if (! gn_cadence_types_enabled()) { + yylval.text = strdup(yytext); + rc = IDENTIFIER; + } else { + yylval.text = 0; + } + break; + + default: yylval.text = 0; + break; } return rc; diff --git a/lexor_keyword.gperf b/lexor_keyword.gperf index 26d7c2fea..f45d9ba99 100644 --- a/lexor_keyword.gperf +++ b/lexor_keyword.gperf @@ -14,6 +14,7 @@ always, K_always and, K_and assign, K_assign begin, K_begin +bool, K_bool buf, K_buf bufif0, K_bufif0 bufif1, K_bufif1 @@ -51,6 +52,7 @@ integer, K_integer join, K_join large, K_large localparam, K_localparam +logic, K_logic macromodule, K_macromodule medium, K_medium module, K_module @@ -110,6 +112,7 @@ weak0, K_weak0 weak1, K_weak1 while, K_while wire, K_wire +wone, K_wone wor, K_wor xnor, K_xnor xor, K_xor diff --git a/main.cc b/main.cc index b89c255d6..796a5a6f2 100644 --- a/main.cc +++ b/main.cc @@ -19,7 +19,7 @@ const char COPYRIGHT[] = * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: main.cc,v 1.90 2005/06/28 04:25:55 steve Exp $" +#ident "$Id: main.cc,v 1.91 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -81,7 +81,13 @@ const char*basedir = "."; const char*target = "null"; +/* + * These are the language support control flags. These support which + * language features (the generation) to support. The generation_flag + * is a major moce, and the gn_* flags control specifc sub-features. + */ generation_t generation_flag = GN_DEFAULT; +bool gn_cadence_types_flag = true; map flags; char*vpi_module_list = 0; @@ -758,6 +764,9 @@ int main(int argc, char*argv[]) /* * $Log: main.cc,v $ + * Revision 1.91 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.90 2005/06/28 04:25:55 steve * Remove reference to SystemVerilog. * diff --git a/netlist.cc b/netlist.cc index cf0c1ff9f..0b2272a21 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.cc,v 1.244 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: netlist.cc,v 1.245 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -79,6 +79,8 @@ ostream& operator<< (ostream&o, NetNet::Type t) case NetNet::WIRE: o << "wire"; break; + case NetNet::WONE: + o << "wone"; } return o; } @@ -237,7 +239,8 @@ NetBus::~NetBus() NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins) : NetObj(s, n, 1), sig_next_(0), sig_prev_(0), - type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0), + type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), + signed_(false), msb_(npins-1), lsb_(0), local_flag_(false), eref_count_(0), lref_count_(0) { assert(s); @@ -274,7 +277,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins) NetNet::NetNet(NetScope*s, perm_string n, Type t, long ms, long ls) : NetObj(s, n, 1), sig_next_(0), sig_prev_(0), type_(t), - port_type_(NOT_A_PORT), signed_(false), msb_(ms), lsb_(ls), + port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), + msb_(ms), lsb_(ls), local_flag_(false), eref_count_(0), lref_count_(0) { assert(s); @@ -372,6 +376,16 @@ void NetNet::port_type(NetNet::PortType t) port_type_ = t; } +ivl_variable_type_t NetNet::data_type() const +{ + return data_type_; +} + +void NetNet::data_type(ivl_variable_type_t t) +{ + data_type_ = t; +} + bool NetNet::get_signed() const { return signed_; @@ -1143,6 +1157,22 @@ const Link& NetDivide::pin_DataB() const return pin(2); } +NetLiteral::NetLiteral(NetScope*sc, perm_string n, const verireal&val) +: NetNode(sc, n, 1), real_(val) +{ + pin(0).set_dir(Link::OUTPUT); + pin(0).set_name(perm_string::literal("O"), 0); +} + +NetLiteral::~NetLiteral() +{ +} + +const verireal& NetLiteral::value_real() const +{ + return real_; +} + NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr, unsigned wa, unsigned wb) : NetNode(sc, n, 3), @@ -2203,6 +2233,9 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.245 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.244 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/netlist.h b/netlist.h index d0042a3a1..a5a45c698 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.h,v 1.344 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: netlist.h,v 1.345 2005/07/07 16:22:49 steve Exp $" #endif /* @@ -31,6 +31,7 @@ # include # include # include +# include "ivl_target.h" # include "verinum.h" # include "verireal.h" # include "StringHeap.h" @@ -65,6 +66,8 @@ class NetFuncDef; struct target; struct functor_t; +ostream& operator << (ostream&o, ivl_variable_type_t val); + /* ========= * A NetObj is anything that has any kind of behavior in the * netlist. Nodes can be gates, registers, etc. and are linked @@ -391,7 +394,8 @@ class NetNet : public NetObj { public: enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1, - SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG }; + SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, + WONE }; enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT }; @@ -410,6 +414,9 @@ class NetNet : public NetObj { PortType port_type() const; void port_type(PortType t); + ivl_variable_type_t data_type() const; + void data_type(ivl_variable_type_t t); + /* If a NetNet is signed, then its value is to be treated as signed. Otherwise, it is unsigned. */ bool get_signed() const; @@ -464,6 +471,7 @@ class NetNet : public NetObj { private: Type type_; PortType port_type_; + ivl_variable_type_t data_type_; bool signed_; bool isint_; // original type of integer @@ -1296,7 +1304,10 @@ class NetCaseCmp : public NetNode { bool eeq_; }; -/* +/* NOTE: This class should be replaced with the NetLiteral class + * below, that is more general in that it supports different types of + * values. + * * This class represents instances of the LPM_CONSTANT device. The * node has only outputs and a constant value. The width is available * by getting the pin_count(), and the value bits are available one at @@ -1323,6 +1334,33 @@ class NetConst : public NetNode { verinum::V*value_; }; +/* + * This class represents instances of the LPM_CONSTANT device. The + * node has only outputs and a constant value. The width is available + * by getting the pin_count(), and the value bits are available one at + * a time. There is no meaning to the aggregation of bits to form a + * wide NetConst object, although some targets may have an easier time + * detecting interesting constructs if they are combined. + */ +class NetLiteral : public NetNode { + + public: + // A read-valued literal. + explicit NetLiteral(NetScope*s, perm_string n, const verireal&val); + ~NetLiteral(); + + ivl_variable_type_t data_type() const; + + const verireal& value_real() const; + + virtual bool emit_node(struct target_t*) const; + virtual void functor_node(Design*, functor_t*); + virtual void dump_node(ostream&, unsigned ind) const; + + private: + verireal real_; +}; + /* * This class represents all manner of logic gates. Pin 0 is OUTPUT and * all the remaining pins are INPUT. The BUFIF[01] gates have the @@ -3467,6 +3505,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.345 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.344 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/pad_to_width.cc b/pad_to_width.cc index ba54bc371..44dac2578 100644 --- a/pad_to_width.cc +++ b/pad_to_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pad_to_width.cc,v 1.18 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: pad_to_width.cc,v 1.19 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -97,6 +97,7 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid) // Make a NetNet for the NetConst to NetConcat link. NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid - net->vector_width()); + tmp->data_type( net->data_type() ); tmp->local_flag(true); connect(cc->pin(2), tmp->pin(0)); @@ -104,6 +105,7 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid) // NetConcat node output pin. tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + tmp->data_type( net->data_type() ); tmp->local_flag(true); connect(cc->pin(0), tmp->pin(0)); @@ -125,6 +127,7 @@ NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid) NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); tmp->set_line(*net); tmp->local_flag(true); + tmp->data_type(net->data_type()); tmp->set_signed(true); connect(tmp->pin(0), se->pin(0)); @@ -146,6 +149,7 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid) NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + tmp->data_type(net->data_type()); tmp->local_flag(true); tmp->set_line(*tmp); connect(ps->pin(0), tmp->pin(0)); @@ -155,6 +159,9 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid) /* * $Log: pad_to_width.cc,v $ + * Revision 1.19 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.18 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/parse.y b/parse.y index b7074f93a..0adf80dd2 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: parse.y,v 1.202 2005/02/19 16:44:38 steve Exp $" +#ident "$Id: parse.y,v 1.203 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -106,6 +106,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; NetNet::Type nettype; PGBuiltin::Type gatetype; NetNet::PortType porttype; + ivl_variable_type_t datatype; PWire*wire; svector*wires; @@ -116,7 +117,6 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; PTaskFuncArg function_type; - struct { svector*range; svector*delay; } range_delay; net_decl_assign_t*net_decl_assign; verinum* number; @@ -132,13 +132,13 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %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_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case %token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable %token K_edge K_else K_end K_endcase K_endfunction K_endmodule %token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for %token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if %token K_initial K_inout K_input K_integer K_join K_large K_localparam -%token K_macromodule +%token K_logic K_macromodule %token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0 %token K_notif1 K_or K_output K_parameter K_pmos K_posedge K_primitive %token K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real K_realtime @@ -149,7 +149,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %token K_time K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand %token K_trior K_trireg K_vectored K_wait K_wand K_weak0 K_weak1 %token K_while K_wire -%token K_wor K_xnor K_xor +%token K_wone K_wor K_xnor K_xor %token K_Shold K_Speriod K_Srecovery K_Srecrem K_Ssetup K_Swidth K_Ssetuphold %token KK_attribute @@ -202,6 +202,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %type net_type var_type net_type_opt %type gatetype %type port_type +%type primitive_type primitive_type_opt %type parameter_value_opt %type function_range_or_type_opt @@ -211,8 +212,6 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %type statement statement_opt %type statement_list -%type range_delay - %type spec_polarity %type specify_path_identifiers @@ -307,28 +306,52 @@ attribute scope is entered, the source may declare new registers and integers. This rule matches those declarations. The containing rule has presumably set up the scope. */ + block_item_decl - : attribute_list_opt K_reg signed_opt range register_variable_list ';' - { pform_set_net_range($5, $4, $3); + : attribute_list_opt K_reg + primitive_type_opt signed_opt range + register_variable_list ';' + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + pform_set_net_range($6, $5, $4, dtype); if ($1) delete $1; } - | attribute_list_opt K_reg signed_opt register_variable_list ';' - { pform_set_net_range($4, 0, $3); + + /* This differs from the above pattern only in the absence of the + range. This is the rule for a scalar. */ + + | attribute_list_opt K_reg + primitive_type_opt signed_opt + register_variable_list ';' + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + pform_set_net_range($5, 0, $4, dtype); if ($1) delete $1; } + + /* Integer declarations are simpler in that they do not have all the + trappings of a general variable declaration. All of that is + implicit in the "integer" of the declaratin. */ + | attribute_list_opt K_integer register_variable_list ';' { pform_set_reg_integer($3); if ($1) delete $1; } + | K_time register_variable_list ';' { pform_set_reg_time($2); } + | K_real list_of_identifiers ';' { pform_make_reals($2, @1.text, @1.first_line); } + | K_realtime list_of_identifiers ';' { pform_make_reals($2, @1.text, @1.first_line); } + | K_parameter parameter_assign_decl ';' | K_localparam localparam_assign_decl ';' @@ -1484,10 +1507,6 @@ module : attribute_list_opt module_start IDENTIFIER module_start : K_module | K_macromodule ; -range_delay : range_opt delay3_opt - { $$.range = $1; $$.delay = $2; } - ; - module_port_list_opt : '(' list_of_ports ')' { $$ = $2; } | '(' list_of_port_declarations ')' { $$ = $2; } @@ -1509,40 +1528,76 @@ module_parameter_port_list ; module_item - : attribute_list_opt net_type signed_opt range_delay list_of_identifiers ';' - { pform_makewire(@2, $4.range, $3, $5, $2, - NetNet::NOT_A_PORT, $1); - if ($4.delay != 0) { - yyerror(@4, "sorry: net delays not supported."); - delete $4.delay; + + /* This rule detects net declarations that possibly include a + primitive type, an optional vector range and signed flag. This + also includes an optional delay set. The values are then applied + to a list of names. If the primitive type is not specified, then + resort to the default type LOGIC. */ + + : attribute_list_opt net_type + primitive_type_opt signed_opt range_opt + delay3_opt + list_of_identifiers ';' + + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + pform_makewire(@2, $5, $4, $7, $2, + NetNet::NOT_A_PORT, dtype, $1); + if ($6 != 0) { + yyerror(@6, "sorry: net delays not supported."); + delete $6; } if ($1) delete $1; } - | attribute_list_opt net_type signed_opt range_delay net_decl_assigns ';' - { pform_makewire(@2, $4.range, $3, $4.delay, - str_strength, $5, $2); + + /* Very similar to the rule above, but this takes a list of + net_decl_assigns, which are = assignment + declarations. */ + + | attribute_list_opt net_type + primitive_type_opt signed_opt range_opt + delay3_opt net_decl_assigns ';' + + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + pform_makewire(@2, $5, $4, $6, + str_strength, $7, $2, dtype); if ($1) { - yyerror(@3, "sorry: Attributes not supported " + yyerror(@2, "sorry: Attributes not supported " "on net declaration assignments."); delete $1; } } - | attribute_list_opt net_type signed_opt drive_strength net_decl_assigns ';' - { pform_makewire(@2, 0, $3, 0, $4, $5, $2); - if ($1) { - yyerror(@4, "sorry: Attributes not supported " - "on net declaration assignments."); - delete $1; - } - } - | K_trireg charge_strength_opt range_delay list_of_identifiers ';' - { yyerror(@1, "sorry: trireg nets not supported."); - delete $3.range; - delete $3.delay; - } - | port_type signed_opt range_delay list_of_identifiers ';' - { pform_set_port_type(@1, $4, $3.range, $2, $1); + /* This form doesn't have the range, but does have strengths. This + gives strength to the assignment drivers. */ + + | attribute_list_opt net_type + primitive_type_opt signed_opt + drive_strength net_decl_assigns ';' + + { ivl_variable_type_t dtype = $3; + if (dtype == IVL_VT_NO_TYPE) + dtype = IVL_VT_LOGIC; + pform_makewire(@2, 0, $4, 0, $5, $6, $2, dtype); + if ($1) { + yyerror(@2, "sorry: Attributes not supported " + "on net declaration assignments."); + delete $1; + } + } + + | K_trireg charge_strength_opt range_opt delay3_opt list_of_identifiers ';' + { yyerror(@1, "sorry: trireg nets not supported."); + delete $3; + delete $4; + } + + | port_type signed_opt range_opt delay3_opt list_of_identifiers ';' + { pform_set_port_type(@1, $5, $3, $2, $1); } /* The next two rules handle Verilog 2001 statements of the form: @@ -1550,11 +1605,13 @@ module_item This creates the wire and sets the port type all at once. */ | port_type net_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, $1, 0); + { pform_makewire(@1, $4, $3, $5, $2, $1, IVL_VT_NO_TYPE, 0); } | K_output var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT, 0); + { pform_makewire(@1, $4, $3, $5, $2, + NetNet::POUTPUT, + IVL_VT_NO_TYPE, 0); } /* var_type declaration (reg variables) cannot be input or output, @@ -1562,20 +1619,22 @@ module_item cannot be attached to a reg. These rules catch that error early. */ | K_input var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINPUT, 0); + { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINPUT, + IVL_VT_NO_TYPE, 0); yyerror(@2, "error: reg variables cannot be inputs."); } | K_inout var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINOUT, 0); + { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINOUT, + IVL_VT_NO_TYPE, 0); yyerror(@2, "error: reg variables cannot be inouts."); } - | port_type signed_opt range_delay error ';' + | port_type signed_opt range_opt delay3_opt error ';' { yyerror(@3, "error: Invalid variable list" " in port declaration."); - if ($3.range) delete $3.range; - if ($3.delay) delete $3.delay; + if ($3) delete $3; + if ($4) delete $4; yyerrok; } @@ -1726,8 +1785,7 @@ module_item reasonable error message can be produced. */ | error ';' - { yyerror(@1, "error: invalid module item. " - "Did you forget an initial or always?"); + { yyerror(@2, "error: invalid module item."); yyerrok; } @@ -1804,6 +1862,14 @@ net_decl_assigns } ; +primitive_type + : K_logic { $$ = IVL_VT_LOGIC; } + | K_bool { $$ = IVL_VT_BOOL; } + | K_real { $$ = IVL_VT_REAL; } + ; + +primitive_type_opt : primitive_type { $$ = $1; } | { $$ = IVL_VT_NO_TYPE; } ; + net_type : K_wire { $$ = NetNet::WIRE; } | K_tri { $$ = NetNet::TRI; } @@ -1815,6 +1881,7 @@ net_type | K_supply1 { $$ = NetNet::SUPPLY1; } | K_wor { $$ = NetNet::WOR; } | K_trior { $$ = NetNet::TRIOR; } + | K_wone { $$ = NetNet::WONE; } ; var_type @@ -2211,12 +2278,14 @@ function_range_or_type_opt register_variable : IDENTIFIER { pform_makewire(@1, $1, NetNet::REG, - NetNet::NOT_A_PORT, 0); + NetNet::NOT_A_PORT, + IVL_VT_NO_TYPE, 0); $$ = $1; } | IDENTIFIER '=' expression { pform_makewire(@1, $1, NetNet::REG, - NetNet::NOT_A_PORT, 0); + NetNet::NOT_A_PORT, + IVL_VT_NO_TYPE, 0); if (! pform_expression_is_constant($3)) yyerror(@3, "error: register declaration assignment" " value must be a constant expression."); @@ -2225,7 +2294,8 @@ register_variable } | IDENTIFIER '[' expression ':' expression ']' { pform_makewire(@1, $1, NetNet::REG, - NetNet::NOT_A_PORT, 0); + NetNet::NOT_A_PORT, + IVL_VT_NO_TYPE, 0); if (! pform_expression_is_constant($3)) yyerror(@3, "error: msb of register range must be constant."); if (! pform_expression_is_constant($5)) @@ -3021,19 +3091,28 @@ udp_port_decl : K_input list_of_identifiers ';' { $$ = pform_make_udp_input_ports($2); } | K_output IDENTIFIER ';' - { PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT); + { PWire*pp = new PWire($2, + NetNet::IMPLICIT, + NetNet::POUTPUT, + IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; $$ = tmp; } | K_reg IDENTIFIER ';' - { PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT); + { PWire*pp = new PWire($2, + NetNet::REG, + NetNet::PIMPLICIT, + IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; $$ = tmp; } | K_reg K_output IDENTIFIER ';' - { PWire*pp = new PWire($3, NetNet::REG, NetNet::POUTPUT); + { PWire*pp = new PWire($3, + NetNet::REG, + NetNet::POUTPUT, + IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; $$ = tmp; diff --git a/pform.cc b/pform.cc index a0f4366e8..3e691fe25 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.cc,v 1.131 2005/05/06 00:25:13 steve Exp $" +#ident "$Id: pform.cc,v 1.132 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -614,7 +614,8 @@ void pform_make_udp(perm_string name, bool synchronous_flag, /* Make the PWire for the output port. */ pins[0] = new PWire(hier_name(out_name), synchronous_flag? NetNet::REG : NetNet::WIRE, - NetNet::POUTPUT); + NetNet::POUTPUT, + IVL_VT_LOGIC); pins[0]->set_file(file); pins[0]->set_lineno(lineno); @@ -627,7 +628,8 @@ void pform_make_udp(perm_string name, bool synchronous_flag, assert(idx < pins.count()); pins[idx] = new PWire(hier_name(*cur), NetNet::WIRE, - NetNet::PINPUT); + NetNet::PINPUT, + IVL_VT_LOGIC); pins[idx]->set_file(file); pins[idx]->set_lineno(lineno); } @@ -691,7 +693,8 @@ void pform_make_udp(perm_string name, bool synchronous_flag, */ static void pform_set_net_range(const char* name, const svector*range, - bool signed_flag) + bool signed_flag, + ivl_variable_type_t dt) { PWire*cur = pform_cur_module->get_wire(hier_name(name)); @@ -712,11 +715,15 @@ static void pform_set_net_range(const char* name, cur->set_range((*range)[0], (*range)[1]); } cur->set_signed(signed_flag); + + if (dt != IVL_VT_NO_TYPE) + cur->set_data_type(dt); } void pform_set_net_range(list*names, svector*range, - bool signed_flag) + bool signed_flag, + ivl_variable_type_t dt) { assert((range == 0) || (range->count() == 2)); @@ -724,7 +731,7 @@ void pform_set_net_range(list*names, ; cur != names->end() ; cur ++ ) { perm_string txt = *cur; - pform_set_net_range(txt, range, signed_flag); + pform_set_net_range(txt, range, signed_flag, dt); } delete names; @@ -1060,7 +1067,7 @@ void pform_module_define_port(const struct vlltype&li, } - cur = new PWire(name, type, port_type); + cur = new PWire(name, type, port_type, IVL_VT_LOGIC); cur->set_file(li.text); cur->set_lineno(li.first_line); @@ -1105,6 +1112,7 @@ void pform_module_define_port(const struct vlltype&li, */ void pform_makewire(const vlltype&li, const char*nm, NetNet::Type type, NetNet::PortType pt, + ivl_variable_type_t dt, svector*attr) { hname_t name = hier_name(nm); @@ -1132,7 +1140,7 @@ void pform_makewire(const vlltype&li, const char*nm, return; } - cur = new PWire(name, type, pt); + cur = new PWire(name, type, pt, dt); cur->set_file(li.text); cur->set_lineno(li.first_line); @@ -1152,14 +1160,15 @@ void pform_makewire(const vlltype&li, list*names, NetNet::Type type, NetNet::PortType pt, + ivl_variable_type_t dt, svector*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; cur ++ ) { perm_string txt = *cur; - pform_makewire(li, txt, type, pt, attr); - pform_set_net_range(txt, range, signed_flag); + pform_makewire(li, txt, type, pt, dt, attr); + pform_set_net_range(txt, range, signed_flag, dt); } delete names; @@ -1173,7 +1182,8 @@ void pform_makewire(const vlltype&li, svector*delay, str_pair_t str, net_decl_assign_t*decls, - NetNet::Type type) + NetNet::Type type, + ivl_variable_type_t dt) { net_decl_assign_t*first = decls->next; decls->next = 0; @@ -1181,8 +1191,8 @@ void pform_makewire(const vlltype&li, while (first) { net_decl_assign_t*next = first->next; - pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, 0); - pform_set_net_range(first->name, range, signed_flag); + pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, dt, 0); + pform_set_net_range(first->name, range, signed_flag, dt); hname_t name = hier_name(first->name); PWire*cur = pform_cur_module->get_wire(name); @@ -1208,7 +1218,7 @@ void pform_set_port_type(perm_string nm, NetNet::PortType pt, hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { - cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT); + cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_LOGIC); cur->set_file(file); cur->set_lineno(lineno); pform_cur_module->add_wire(cur); @@ -1297,7 +1307,8 @@ svector*pform_make_task_ports(NetNet::PortType pt, if (curw) { curw->set_port_type(pt); } else { - curw = new PWire(name, NetNet::IMPLICIT_REG, pt); + curw = new PWire(name, NetNet::IMPLICIT_REG, pt, + IVL_VT_LOGIC); curw->set_file(file); curw->set_lineno(lineno); pform_cur_module->add_wire(curw); @@ -1455,7 +1466,7 @@ void pform_set_port_type(const struct vlltype&li, perm_string txt = *cur; pform_set_port_type(txt, pt, li.text, li.first_line); if (range) - pform_set_net_range(txt, range, signed_flag); + pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE); } delete names; @@ -1468,12 +1479,15 @@ static void pform_set_reg_integer(const char*nm) hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { - cur = new PWire(name, NetNet::INTEGER, NetNet::NOT_A_PORT); + cur = new PWire(name, NetNet::INTEGER, + NetNet::NOT_A_PORT, + IVL_VT_LOGIC); cur->set_signed(true); pform_cur_module->add_wire(cur); } else { bool rc = cur->set_wire_type(NetNet::INTEGER); assert(rc); + cur->set_data_type(IVL_VT_LOGIC); cur->set_signed(true); } assert(cur); @@ -1499,11 +1513,13 @@ static void pform_set_reg_time(const char*nm) hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); if (cur == 0) { - cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT); + cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC); pform_cur_module->add_wire(cur); } else { bool rc = cur->set_wire_type(NetNet::REG); assert(rc); + rc = cur->set_data_type(IVL_VT_LOGIC); + assert(rc); } assert(cur); @@ -1533,7 +1549,8 @@ svector* pform_make_udp_input_ports(list*names) perm_string txt = *cur; PWire*pp = new PWire(hname_t(txt), NetNet::IMPLICIT, - NetNet::PINPUT); + NetNet::PINPUT, + IVL_VT_LOGIC); (*out)[idx] = pp; idx += 1; } @@ -1600,6 +1617,9 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.132 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.131 2005/05/06 00:25:13 steve * Handle synthesis of concatenation expressions. * diff --git a/pform.h b/pform.h index 544c83ce0..cd3552c52 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.h,v 1.82 2004/12/11 02:31:27 steve Exp $" +#ident "$Id: pform.h,v 1.83 2005/07/07 16:22:49 steve Exp $" #endif # include "netlist.h" @@ -171,23 +171,31 @@ extern verinum* pform_verinum_with_size(verinum*s, verinum*val, * go into a module that is currently opened. */ extern void pform_makewire(const struct vlltype&li, const char*name, - NetNet::Type type, NetNet::PortType pt, + NetNet::Type type, + NetNet::PortType pt, + ivl_variable_type_t, svector*attr); +/* This form handles simple declarations */ extern void pform_makewire(const struct vlltype&li, svector*range, bool signed_flag, list*names, NetNet::Type type, NetNet::PortType, + ivl_variable_type_t, svector*attr); + +/* This form handles assignment declarations. */ extern void pform_makewire(const struct vlltype&li, svector*range, bool signed_flag, svector*delay, str_pair_t str, net_decl_assign_t*assign_list, - NetNet::Type type); + NetNet::Type type, + ivl_variable_type_t); + extern void pform_make_reginit(const struct vlltype&li, const char*name, PExpr*expr); @@ -203,7 +211,9 @@ extern void pform_set_port_type(perm_string nm, NetNet::PortType pt, const char*file, unsigned lineno); extern void pform_set_net_range(list*names, - svector*, bool); + svector*, + bool signed_flag, + ivl_variable_type_t); extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r); extern void pform_set_reg_integer(list*names); extern void pform_set_reg_time(list*names); @@ -295,6 +305,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.83 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.82 2004/12/11 02:31:27 steve * Rework of internals to carry vectors through nexus instead * of single bits. Make the ivl, tgt-vvp and vvp initial changes diff --git a/pform_dump.cc b/pform_dump.cc index a70425cc9..e1241a742 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform_dump.cc,v 1.88 2004/10/04 01:10:55 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.89 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -207,21 +207,23 @@ void PWire::dump(ostream&out) const switch (port_type_) { case NetNet::PIMPLICIT: - out << " (implicit input)"; + out << " implicit input"; break; case NetNet::PINPUT: - out << " (input)"; + out << " input"; break; case NetNet::POUTPUT: - out << " (output)"; + out << " output"; break; case NetNet::PINOUT: - out << " (input output)"; + out << " inout"; break; case NetNet::NOT_A_PORT: break; } + out << " " << data_type_; + if (signed_) { out << " signed"; } @@ -909,6 +911,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.89 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.88 2004/10/04 01:10:55 steve * Clean up spurious trailing white space. * diff --git a/t-dll-api.cc b/t-dll-api.cc index c27ca952e..169c25f67 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll-api.cc,v 1.128 2005/06/13 23:22:37 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.129 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -123,13 +123,26 @@ extern "C" unsigned ivl_memory_width(ivl_memory_t net) } +extern "C" ivl_variable_type_t ivl_const_type(ivl_net_const_t net) +{ + assert(net); + return net->type; +} + extern "C" const char*ivl_const_bits(ivl_net_const_t net) { assert(net); - if (net->width_ <= sizeof(char*)) - return net->b.bit_; - else - return net->b.bits_; + switch (net->type) { + + case IVL_VT_LOGIC: + if (net->width_ <= sizeof(net->b.bit_)) + return net->b.bit_; + else + return net->b.bits_; + + default: + return 0; + } } extern "C" ivl_nexus_t ivl_const_nex(ivl_net_const_t net) @@ -138,6 +151,13 @@ extern "C" ivl_nexus_t ivl_const_nex(ivl_net_const_t net) return net->pin_; } +extern "C" double ivl_const_real(ivl_net_const_t net) +{ + assert(net); + assert(net->type == IVL_VT_REAL); + return net->b.real_value; +} + extern "C" int ivl_const_signed(ivl_net_const_t net) { assert(net); @@ -1240,7 +1260,14 @@ extern "C" ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx) extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net) { assert(net); - return net->n.sig; + switch (net->type_) { + case IVL_LVAL_REG: + case IVL_LVAL_NET: + case IVL_LVAL_MUX: + return net->n.sig; + default: + return 0; + } } extern "C" const char* ivl_nexus_name(ivl_nexus_t net) @@ -1677,6 +1704,11 @@ extern "C" int ivl_signal_integer(ivl_signal_t net) return net->isint_; } +extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net) +{ + return net->data_type; +} + extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net) { return net->type_; @@ -2040,6 +2072,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.129 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.128 2005/06/13 23:22:37 steve * Fix compile errors. * diff --git a/t-dll.cc b/t-dll.cc index 042d38f05..e6a099941 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll.cc,v 1.151 2005/06/26 18:08:46 steve Exp $" +#ident "$Id: t-dll.cc,v 1.152 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -1849,11 +1849,13 @@ bool dll_target::net_const(const NetConst*net) struct ivl_net_const_s *obj = new struct ivl_net_const_s; + obj->type = IVL_VT_LOGIC; + /* constants have a single vector output. */ assert(net->pin_count() == 1); obj->width_ = net->width(); - if (obj->width_ <= sizeof(char*)) { + if (obj->width_ <= sizeof(obj->b.bit_)) { bits = obj->b.bit_; } else { @@ -1897,6 +1899,35 @@ bool dll_target::net_const(const NetConst*net) return true; } +bool dll_target::net_literal(const NetLiteral*net) +{ + + struct ivl_net_const_s *obj = new struct ivl_net_const_s; + + obj->type = IVL_VT_REAL; + obj->width_ = 1; + obj->signed_ = 1; + obj->b.real_value = net->value_real().as_double(); + + /* Connect to all the nexus objects. Note that the one-bit + case can be handled more efficiently without allocating + array space. */ + + ivl_drive_t drv0, drv1; + drive_from_link(net->pin(0), drv0, drv1); + const Nexus*nex = net->pin(0).nexus(); + assert(nex->t_cookie()); + obj->pin_ = (ivl_nexus_t) nex->t_cookie(); + nexus_con_add(obj->pin_, obj, 0, drv0, drv1); + + des_.nconsts += 1; + des_.consts = (ivl_net_const_t*) + realloc(des_.consts, des_.nconsts * sizeof(ivl_net_const_t)); + des_.consts[des_.nconsts-1] = obj; + + return true; +} + void dll_target::net_probe(const NetEvProbe*net) { } @@ -2079,6 +2110,7 @@ void dll_target::signal(const NetNet*net) break; } + obj->data_type = net->data_type(); obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); @@ -2111,6 +2143,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.152 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.151 2005/06/26 18:08:46 steve * Fix uninitialzied attr pointers for UDP devices. * diff --git a/t-dll.h b/t-dll.h index 848ebf199..43a7bac53 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll.h,v 1.126 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: t-dll.h,v 1.127 2005/07/07 16:22:49 steve Exp $" #endif # include "target.h" @@ -89,6 +89,7 @@ struct dll_target : public target_t, public expr_scan_t { void net_assign(const NetAssign_*); bool net_function(const NetUserFunc*); bool net_const(const NetConst*); + bool net_literal(const NetLiteral*); void net_probe(const NetEvProbe*); bool sign_extend(const NetSignExtend*); @@ -396,14 +397,16 @@ struct ivl_lval_s { }; /* - * This object represents a vector constant, possibly signed, in a + * This object represents a literal constant, possibly signed, in a * structural context. */ struct ivl_net_const_s { + ivl_variable_type_t type; unsigned width_; unsigned signed_ : 1; union { + double real_value; char bit_[sizeof(char*)]; char *bits_; } b; @@ -575,6 +578,7 @@ struct ivl_scope_s { struct ivl_signal_s { ivl_signal_type_t type_; ivl_signal_port_t port_; + ivl_variable_type_t data_type; unsigned width_; unsigned signed_ : 1; @@ -686,6 +690,9 @@ struct ivl_variable_s { /* * $Log: t-dll.h,v $ + * Revision 1.127 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.126 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/target.cc b/target.cc index 130d7a58b..418e4c424 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: target.cc,v 1.75 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: target.cc,v 1.76 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -187,6 +187,13 @@ bool target_t::net_function(const NetUserFunc*net) return false; } +bool target_t::net_literal(const NetLiteral*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled LITERAL node." << endl; + return false; +} + void target_t::net_probe(const NetEvProbe*net) { cerr << "target (" << typeid(*this).name() << "): " @@ -436,6 +443,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.76 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.75 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/target.h b/target.h index a31ab96aa..917cde5bf 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: target.h,v 1.72 2005/05/24 01:44:28 steve Exp $" +#ident "$Id: target.h,v 1.73 2005/07/07 16:22:49 steve Exp $" #endif # include "netlist.h" @@ -98,6 +98,7 @@ struct target_t { virtual void net_case_cmp(const NetCaseCmp*); virtual bool net_const(const NetConst*); virtual bool net_function(const NetUserFunc*); + virtual bool net_literal(const NetLiteral*); virtual void net_probe(const NetEvProbe*); virtual bool sign_extend(const NetSignExtend*); @@ -173,6 +174,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.73 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.72 2005/05/24 01:44:28 steve * Do sign extension of structuran nets. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 9d87d7e49..d68268a0c 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.128 2005/06/26 18:09:24 steve Exp $" +#ident "$Id: stub.c,v 1.129 2005/07/07 16:22:49 steve Exp $" #endif # include "config.h" @@ -1031,13 +1031,26 @@ static void signal_nexus_const(ivl_signal_t sig, const char*dr0 = str_tab[ivl_nexus_ptr_drive0(ptr)]; const char*dr1 = str_tab[ivl_nexus_ptr_drive1(ptr)]; - const char*bits = ivl_const_bits(con); + const char*bits; unsigned idx, width = ivl_const_width(con); fprintf(out, " const-"); - for (idx = 0 ; idx < width ; idx += 1) { - fprintf(out, "%c", bits[width-idx-1]); + switch (ivl_const_type(con)) { + case IVL_VT_LOGIC: + bits = ivl_const_bits(con); + for (idx = 0 ; idx < width ; idx += 1) { + fprintf(out, "%c", bits[width-idx-1]); + } + break; + + case IVL_VT_REAL: + fprintf(out, "%lf", ivl_const_real(con)); + break; + + default: + fprintf(out, "????"); + break; } fprintf(out, " (%s0, %s1, width=%u)\n", dr0, dr1, width); @@ -1047,6 +1060,12 @@ static void signal_nexus_const(ivl_signal_t sig, "width of connected constant vector.\n"); stub_errors += 1; } + + if (ivl_signal_data_type(sig) != ivl_const_type(con)) { + fprintf(out, "ERROR: Signal data type does not match" + " literal type.\n"); + stub_errors += 1; + } } @@ -1057,6 +1076,7 @@ static void show_signal(ivl_signal_t net) const char*type = "?"; const char*port = ""; + const char*data_type = "?"; const char*sign = ivl_signal_signed(net)? "signed" : "unsigned"; switch (ivl_signal_type(net)) { @@ -1094,10 +1114,29 @@ static void show_signal(ivl_signal_t net) break; } + switch (ivl_signal_data_type(net)) { + + case IVL_VT_BOOL: + data_type = "bool"; + break; + + case IVL_VT_LOGIC: + data_type = "logic"; + break; + + case IVL_VT_REAL: + data_type = "real"; + break; + + default: + data_type = "?data?"; + break; + } + nex = ivl_signal_nex(net); - fprintf(out, " %s %s %s[%d:%d] %s nexus=%s\n", - type, sign, port, + fprintf(out, " %s %s %s%s[%d:%d] %s nexus=%s\n", + type, sign, port, data_type, ivl_signal_msb(net), ivl_signal_lsb(net), ivl_signal_basename(net), ivl_signal_width(net), ivl_nexus_name(nex)); @@ -1130,6 +1169,12 @@ static void show_signal(ivl_signal_t net) ivl_signal_width(sig)); stub_errors += 1; } + + if (ivl_signal_data_type(sig) != ivl_signal_data_type(net)) { + fprintf(out, " (ERROR: data type mismatch)"); + stub_errors += 1; + } + fprintf(out, "\n"); } else if ((log = ivl_nexus_ptr_log(ptr))) { @@ -1442,6 +1487,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.129 2005/07/07 16:22:49 steve + * Generalize signals to carry types. + * * Revision 1.128 2005/06/26 18:09:24 steve * Check width of part select based on direction. * diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 6e9ef4e3e..b68c62cb1 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_real.c,v 1.11 2004/10/04 01:10:57 steve Exp $" +#ident "$Id: eval_real.c,v 1.12 2005/07/07 16:22:50 steve Exp $" #endif /* @@ -227,7 +227,7 @@ static int draw_sfunc_real(ivl_expr_t exp) * The real value of a signal is the integer value of a signal * converted to real. */ -static int draw_signal_real(ivl_expr_t exp) +static int draw_signal_real_logic(ivl_expr_t exp) { int res = allocate_word(); struct vector_info sv = draw_eval_expr(exp, 0); @@ -240,6 +240,33 @@ static int draw_signal_real(ivl_expr_t exp) return res; } +static int draw_signal_real_real(ivl_expr_t exp) +{ + ivl_signal_t sig = ivl_expr_signal(exp); + int res = allocate_word(); + + fprintf(vvp_out, " %%load/wr %d, V_%s;\n", + res, vvp_signal_label(sig)); + + return res; +} + +static int draw_signal_real(ivl_expr_t exp) +{ + ivl_signal_t sig = ivl_expr_signal(exp); + switch (ivl_signal_data_type(sig)) { + case IVL_VT_LOGIC: + return draw_signal_real_logic(exp); + case IVL_VT_REAL: + return draw_signal_real_real(exp); + default: + fprintf(stderr, "internal error: signal_data_type=%d\n", + ivl_signal_data_type(sig)); + assert(0); + return -1; + } +} + int draw_eval_real(ivl_expr_t exp) { int res = 0; @@ -298,6 +325,9 @@ int draw_eval_real(ivl_expr_t exp) /* * $Log: eval_real.c,v $ + * Revision 1.12 2005/07/07 16:22:50 steve + * Generalize signals to carry types. + * * Revision 1.11 2004/10/04 01:10:57 steve * Clean up spurious trailing white space. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index d4cde5193..a33468199 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.113 2005/06/15 01:33:33 steve Exp $" +#ident "$Id: vvp_process.c,v 1.114 2005/07/07 16:22:50 steve Exp $" #endif # include "vvp_priv.h" @@ -312,6 +312,11 @@ static int show_stmt_assign_vector(ivl_statement_t net) return 0; } +/* + * This function assigns a value to a real .variable. This is destined + * for /dev/null when typed ivl_signal_t takes over all the real + * variable support. + */ static int show_stmt_assign_real(ivl_statement_t net) { int res; @@ -332,6 +337,26 @@ static int show_stmt_assign_real(ivl_statement_t net) return 0; } +static int show_stmt_assign_sig_real(ivl_statement_t net) +{ + int res; + ivl_lval_t lval; + ivl_signal_t var; + + res = draw_eval_real(ivl_stmt_rval(net)); + clr_word(res); + + assert(ivl_stmt_lvals(net) == 1); + lval = ivl_stmt_lval(net, 0); + var = ivl_lval_sig(lval); + assert(var != 0); + + fprintf(vvp_out, " %%set/wr V_%s, %d;\n", + vvp_signal_label(var), res); + + return 0; +} + static int show_stmt_assign(ivl_statement_t net) { ivl_lval_t lval; @@ -356,7 +381,18 @@ static int show_stmt_assign(ivl_statement_t net) } } else { - return show_stmt_assign_vector(net); + ivl_signal_t sig = ivl_lval_sig(lval); + if (sig) switch (ivl_signal_data_type(sig)) { + + case IVL_VT_REAL: + return show_stmt_assign_sig_real(net); + + default: + return show_stmt_assign_vector(net); + + } else { + return show_stmt_assign_vector(net); + } } return 0; @@ -1461,6 +1497,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.114 2005/07/07 16:22:50 steve + * Generalize signals to carry types. + * * Revision 1.113 2005/06/15 01:33:33 steve * Fix bit offsets when processing lval concatenation. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index b41d31d77..096e5d921 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_scope.c,v 1.129 2005/06/17 03:46:52 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.130 2005/07/07 16:22:50 steve Exp $" #endif # include "vvp_priv.h" @@ -216,6 +216,20 @@ unsigned width_of_nexus(ivl_nexus_t nex) return 0; } +ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex) +{ + unsigned idx; + for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); + ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); + if (sig != 0) + return ivl_signal_data_type(sig); + } + + /* shouldn't happen! */ + return IVL_VT_NO_TYPE; +} + ivl_nexus_ptr_t ivl_logic_pin_ptr(ivl_net_logic_t net, unsigned pin) { @@ -530,19 +544,34 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) cptr = ivl_nexus_ptr_con(nptr); if (cptr) { - /* Constants should have exactly 1 pin, with a vector value. */ + /* Constants should have exactly 1 pin, with a literal value. */ assert(nptr_pin == 0); - if ((ivl_nexus_ptr_drive0(nptr) == IVL_DR_STRONG) - && (ivl_nexus_ptr_drive1(nptr) == IVL_DR_STRONG)) { + switch (ivl_const_type(cptr)) { + case IVL_VT_LOGIC: + case IVL_VT_BOOL: + if ((ivl_nexus_ptr_drive0(nptr) == IVL_DR_STRONG) + && (ivl_nexus_ptr_drive1(nptr) == IVL_DR_STRONG)) { - draw_C4_to_string(result, sizeof(result), cptr); + draw_C4_to_string(result, sizeof(result), cptr); - } else { - draw_C8_to_string(result, sizeof(result), cptr, - ivl_nexus_ptr_drive0(nptr), - ivl_nexus_ptr_drive1(nptr)); + } else { + draw_C8_to_string(result, sizeof(result), cptr, + ivl_nexus_ptr_drive0(nptr), + ivl_nexus_ptr_drive1(nptr)); + } + break; + + case IVL_VT_REAL: + snprintf(result, sizeof(result), + "Cr<%lg>", ivl_const_real(cptr)); + break; + + default: + assert(0); + break; } + return result; } @@ -769,11 +798,19 @@ static void draw_reg_in_scope(ivl_signal_t sig) int msb = ivl_signal_msb(sig); int lsb = ivl_signal_lsb(sig); - const char*signed_flag = ivl_signal_integer(sig) ? "/i" : + const char*datatype_flag = ivl_signal_integer(sig) ? "/i" : ivl_signal_signed(sig)? "/s" : ""; + switch (ivl_signal_data_type(sig)) { + case IVL_VT_LOGIC: + break; + case IVL_VT_REAL: + datatype_flag = "/real"; + break; + } + fprintf(vvp_out, "V_%s .var%s \"%s\", %d, %d;\n", - vvp_signal_label(sig), signed_flag, + vvp_signal_label(sig), datatype_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb); } @@ -788,7 +825,7 @@ static void draw_net_in_scope(ivl_signal_t sig) typedef const char*const_charp; const char* arg; - const char*signed_flag = ivl_signal_signed(sig)? "/s" : ""; + const char*datatype_flag = ivl_signal_signed(sig)? "/s" : ""; /* Skip the local signal. */ if (ivl_signal_local(sig)) @@ -800,8 +837,16 @@ static void draw_net_in_scope(ivl_signal_t sig) arg = draw_net_input(nex); } + switch (ivl_signal_data_type(sig)) { + case IVL_VT_LOGIC: + break; + case IVL_VT_REAL: + datatype_flag = "/real"; + break; + } + fprintf(vvp_out, "V_%s .net%s \"%s\", %d, %d, %s;\n", - vvp_signal_label(sig), signed_flag, + vvp_signal_label(sig), datatype_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, arg); } @@ -1332,6 +1377,12 @@ static void draw_lpm_add(ivl_lpm_t net) const char*src_table[2]; unsigned width; const char*type = ""; + ivl_variable_type_t dta = data_type_of_nexus(ivl_lpm_data(net,0)); + ivl_variable_type_t dtb = data_type_of_nexus(ivl_lpm_data(net,1)); + ivl_variable_type_t dto = IVL_VT_LOGIC; + + if (dta == IVL_VT_REAL && dtb == IVL_VT_REAL) + dto = IVL_VT_REAL; width = ivl_lpm_width(net); @@ -1340,13 +1391,18 @@ static void draw_lpm_add(ivl_lpm_t net) type = "sum"; break; case IVL_LPM_SUB: - type = "sub"; + if (dto == IVL_VT_REAL) + type = "sub.r"; + else + type = "sub"; break; case IVL_LPM_MULT: type = "mult"; break; case IVL_LPM_DIVIDE: - if (ivl_lpm_signed(net)) + if (dto == IVL_VT_REAL) + type = "div.r"; + else if (ivl_lpm_signed(net)) type = "div.s"; else type = "div"; @@ -1905,10 +1961,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* Scan the scope for word variables. */ for (idx = 0 ; idx < ivl_scope_vars(net) ; idx += 1) { ivl_variable_t var = ivl_scope_var(net, idx); - const char*type = "real"; - fprintf(vvp_out, "W_%s .word %s, \"%s\";\n", - vvp_word_label(var), type, + fprintf(vvp_out, "W_%s .var/real \"%s\", 0, 0;\n", + vvp_word_label(var), ivl_variable_name(var)); } @@ -1955,6 +2010,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.130 2005/07/07 16:22:50 steve + * Generalize signals to carry types. + * * Revision 1.129 2005/06/17 03:46:52 steve * Make functors know their own width. *