Generalize signals to carry types.

This commit is contained in:
steve 2005-07-07 16:22:49 +00:00
parent 3ac79c294a
commit 75ad90534b
31 changed files with 922 additions and 171 deletions

13
PExpr.h
View File

@ -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 <string>
@ -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.
*

View File

@ -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 <assert.h>
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.
*

19
PWire.h
View File

@ -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.
*

View File

@ -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

View File

@ -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 <list>
@ -94,7 +94,8 @@ extern list<const char*>library_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.
*

View File

@ -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 << "<no_type>";
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.
*

View File

@ -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.
*

View File

@ -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.
*

10
emit.cc
View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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;

View File

@ -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

11
main.cc
View File

@ -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<string,const char*> 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.
*

View File

@ -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.
*

View File

@ -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 <string>
# include <map>
# include <list>
# 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.
*

View File

@ -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.
*

189
parse.y
View File

@ -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<PWire*>*wires;
@ -116,7 +117,6 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
PTaskFuncArg function_type;
struct { svector<PExpr*>*range; svector<PExpr*>*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 <nettype> net_type var_type net_type_opt
%type <gatetype> gatetype
%type <porttype> port_type
%type <datatype> primitive_type primitive_type_opt
%type <parmvalue> parameter_value_opt
%type <function_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 statement_opt
%type <statement_list> statement_list
%type <range_delay> range_delay
%type <letter> spec_polarity
%type <perm_strings> 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 <name> = <expr> 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<PWire*>*tmp = new svector<PWire*>(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<PWire*>*tmp = new svector<PWire*>(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<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
$$ = tmp;

View File

@ -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<PExpr*>*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<perm_string>*names,
svector<PExpr*>*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<perm_string>*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<named_pexpr_t*>*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<perm_string>*names,
NetNet::Type type,
NetNet::PortType pt,
ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr)
{
for (list<perm_string>::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<PExpr*>*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<PWire*>*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<PWire*>* pform_make_udp_input_ports(list<perm_string>*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.
*

21
pform.h
View File

@ -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<named_pexpr_t*>*attr);
/* This form handles simple declarations */
extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range,
bool signed_flag,
list<perm_string>*names,
NetNet::Type type,
NetNet::PortType,
ivl_variable_type_t,
svector<named_pexpr_t*>*attr);
/* This form handles assignment declarations. */
extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range,
bool signed_flag,
svector<PExpr*>*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<perm_string>*names,
svector<PExpr*>*, bool);
svector<PExpr*>*,
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<perm_string>*names);
extern void pform_set_reg_time(list<perm_string>*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

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

11
t-dll.h
View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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 <width=%u> nexus=%s\n",
type, sign, port,
fprintf(out, " %s %s %s%s[%d:%d] %s <width=%u> 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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*