Compare commits

..
25 Commits
Author SHA1 Message Date
steve 87e813766a Detect and ignore specify edge expressions 2007-06-14 03:50:00 +00:00
steve e24e77660f Detect and use the nan function. 2007-06-13 01:03:57 +00:00
steve 8ec6d9983d Put instantiated modules in the proper generated scope. 2007-06-12 04:05:45 +00:00
steve ae82eccdc4 handle constant inf values. 2007-06-12 02:36:58 +00:00
steve fa18d9bc01 Do not propogate until initialized. 2007-06-12 02:25:00 +00:00
steve 16ec4cb685 displan pmos gates. 2007-06-12 02:23:40 +00:00
steve 6f08f92ffc Prepare for snapshot 20070608 2007-06-09 01:06:51 +00:00
steve 0a38499941 Properly handle signed conversion to real 2007-06-07 03:20:15 +00:00
steve 55f8e5d364 int vs long expressions on 64bit arch (ldoolitt) 2007-06-05 21:52:22 +00:00
steve b631268f56 Error resiliency (ldoolitt) 2007-06-05 21:35:51 +00:00
steve 1a8ffe2a9c More standard PLI_BYTE8. 2007-06-05 21:32:30 +00:00
steve e4bcc87dc1 Upward names may reference modules by module_name. 2007-06-05 04:18:09 +00:00
steve 34111a25cb Bring in .SFT file automatically if -m used. 2007-06-05 01:56:12 +00:00
steve 8fd42fbf61 Build errors in picky GCC compilers. 2007-06-04 19:14:06 +00:00
steve 129a064e1a Handle bit/part select of array words in nets. 2007-06-04 02:19:07 +00:00
steve c7d97f4146 Properly evaluate scope path expressions. 2007-06-02 03:42:12 +00:00
steve 1f9a246c6d Fix warning (ldolittle) 2007-05-31 18:36:06 +00:00
steve 17fd3bae15 Missing return value to perm_string dump 2007-05-31 18:35:50 +00:00
steve 29aa68302e Add elsif support (Martin Whitaker) 2007-05-30 23:21:20 +00:00
steve 8dcd09797f Fix uninitialized lineno variable. 2007-05-25 18:21:39 +00:00
steve ddd36ecb6c Rework the heirarchical identifier parse syntax and pform
to handle more general combinations of heirarch and bit selects.
2007-05-24 04:07:11 +00:00
steve 67b1eee7ce Better configuration messages (Alan Feldstein) 2007-05-16 23:59:12 +00:00
steve 629c6e9a40 Fix hname_t use of space for 1 perm_string. 2007-05-16 19:12:33 +00:00
steve 6ea1337be0 Trace file line buffer must be static. 2007-05-08 22:01:26 +00:00
steve b981c81d37 Rework hname_t to use perm_strings. 2007-04-26 03:06:21 +00:00
68 changed files with 2091 additions and 1354 deletions
+58 -186
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -29,235 +29,107 @@
# include <malloc.h>
#endif
hname_t::hname_t()
{
item_ = 0;
count_ = 0;
number_ = INT_MIN;
}
hname_t::hname_t(const char*text)
hname_t::hname_t(perm_string text)
{
item_ = strdup(text);
count_ = 1;
name_ = text;
number_ = INT_MIN;
}
hname_t::hname_t(perm_string text, int num)
{
name_ = text;
number_ = num;
}
hname_t::hname_t(const hname_t&that)
{
count_ = that.count_;
switch (count_) {
case 0:
item_ = 0;
break;
case 1:
item_ = strdup(that.item_);
break;
default:
array_ = new char*[count_];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
array_[idx] = strdup(that.array_[idx]);
break;
}
name_ = that.name_;
number_ = that.number_;
}
hname_t& hname_t::operator = (const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
return *this;
}
hname_t::~hname_t()
{
switch (count_) {
case 0:
break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
}
unsigned hname_t::component_count() const
perm_string hname_t::peek_name(void) const
{
return count_;
return name_;
}
void hname_t::append(const char*text)
bool hname_t::has_number() const
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = item_;
tmp[1] = strdup(text);
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx] = array_[idx];
delete[]array_;
array_ = tmp;
array_[count_] = strdup(text);
count_ += 1;
}
return number_ != INT_MIN;
}
void hname_t::prepend(const char*text)
int hname_t::peek_number() const
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = strdup(text);
tmp[1] = item_;
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
tmp[0] = strdup(text);
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx+1] = array_[idx];
delete[]array_;
array_ = tmp;
count_ += 1;
}
}
char* hname_t::remove_tail_name()
{
if (count_ == 0)
return 0;
if (count_ == 1) {
char*tmp = item_;
count_ = 0;
item_ = 0;
return tmp;
}
if (count_ == 2) {
char*tmp1 = array_[0];
char*tmp2 = array_[1];
delete[]array_;
count_ = 1;
item_ = tmp1;
return tmp2;
}
char*tmpo = array_[count_-1];
char**tmpa = new char*[count_-1];
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
tmpa[idx] = array_[idx];
delete[]array_;
array_ = tmpa;
count_ -= 1;
return tmpo;
}
const char* hname_t::peek_name(unsigned idx) const
{
if (idx >= count_)
return 0;
if (count_ == 1)
return item_;
return array_[idx];
}
const char* hname_t::peek_tail_name() const
{
switch (count_) {
case 0:
return 0;
case 1:
return item_;
default:
return array_[count_-1];
}
return number_;
}
bool operator < (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp < 0)
return true;
if (cmp > 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc && !rc)
int cmp = strcmp(l.peek_name(), r.peek_name());
if (cmp < 0) return true;
if (cmp > 0) return false;
if (l.has_number() && r.has_number())
return l.peek_number() < r.peek_number();
else
return false;
if (rc && !lc)
return true;
// Must be ==
return false;
}
bool operator == (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp != 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
if (l.peek_name() == r.peek_name()) {
if (l.has_number() && r.has_number())
return l.peek_number() == r.peek_number();
else
return true;
}
if (lc || rc)
return false;
// Must be ==
return true;
return false;
}
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
ostream& operator<< (ostream&out, const hname_t&that)
{
switch (that.count_) {
case 0:
if (that.peek_name() == 0) {
out << "";
return out;
case 1:
out << that.item_;
return out;
default:
out << that.array_[0];
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
out << "." << that.array_[idx];
return out;
}
out << that.peek_name();
if (that.has_number())
out << "[" << that.peek_number() << "]";
return out;
}
/*
* $Log: HName.cc,v $
* Revision 1.8 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.6 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
+31 -33
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2007 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#endif
# include <iostream>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
@@ -30,59 +31,56 @@ using namespace std;
#endif
/*
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
* This class represents a component of a Verilog hierarchical name. A
* hierarchical component contains a name string (prepresented here
* with a perm_string) and an optional signed number. This signed
* number is used if the scope is part of an array, for example an
* array of module instances or a loop generated scope.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (const char*text);
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
hname_t (const hname_t&that);
~hname_t();
// This method adds a name to the end of the hierarchical
// path. This becomes a new base name.
void append(const char*text);
hname_t& operator= (const hname_t&);
// This method adds a name to the *front* of the hierarchical
// path. The base name remains the same, unless this is the
// only component.
void prepend(const char*text);
// Return the string part of the hname_t.
perm_string peek_name(void) const;
// This method removes the tail name from the hierarchy, and
// returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
// Return the given component in the hierarchical name. If the
// idx is too large, return 0.
const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
// Return the number of components in the hierarchical
// name. If this is a simple name, this will return 1.
unsigned component_count() const;
friend ostream& operator<< (ostream&, const hname_t&);
bool has_number() const;
int peek_number() const;
private:
union {
char**array_;
char* item_;
};
unsigned count_;
perm_string name_;
// If the number is anything other then INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
int number_;
private: // not implemented
hname_t& operator= (const hname_t&);
};
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.7 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.5 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
+2 -2
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.180 2007/02/06 05:07:31 steve Exp $"
#ident "$Id: Makefile.in,v 1.181 2007/05/24 04:07:11 steve Exp $"
#
#
SHELL = /bin/sh
@@ -108,7 +108,7 @@ load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
+7 -8
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.cc,v 1.26 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -111,9 +111,9 @@ unsigned Module::find_port(const char*name) const
}
PWire* Module::get_wire(const hname_t&name) const
PWire* Module::get_wire(const pform_name_t&name) const
{
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
@@ -133,11 +133,6 @@ PGate* Module::get_gate(perm_string name)
return 0;
}
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
const list<PGate*>& Module::get_gates() const
{
return gates_;
@@ -151,6 +146,10 @@ const list<PProcess*>& Module::get_behaviors() const
/*
* $Log: Module.cc,v $
* Revision 1.27 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.26 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
+9 -5
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.42 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
#endif
# include <list>
@@ -30,6 +30,7 @@
# include "named.h"
# include "LineInfo.h"
# include "netlist.h"
# include "pform_types.h"
class PEvent;
class PExpr;
class PEIdent;
@@ -98,7 +99,7 @@ class Module : public LineInfo {
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<hname_t,PExpr*>defparms;
map<pform_name_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -150,10 +151,9 @@ class Module : public LineInfo {
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const hname_t&name) const;
PWire* get_wire(const pform_name_t&name) const;
PGate* get_gate(perm_string name);
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
@@ -168,7 +168,7 @@ class Module : public LineInfo {
private:
perm_string name_;
map<hname_t,PWire*> wires_;
map<pform_name_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
@@ -182,6 +182,10 @@ class Module : public LineInfo {
/*
* $Log: Module.h,v $
* Revision 1.43 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.42 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
+32 -16
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.cc,v 1.38 2006/10/30 05:44:49 steve Exp $"
#ident "$Id: PExpr.cc,v 1.39 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -93,13 +93,26 @@ PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
static pform_name_t pn_from_ps(perm_string n)
{
name_component_t tmp_name (n);
pform_name_t tmp;
tmp.push_back(tmp_name);
return tmp;
}
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n))
{
}
@@ -165,33 +178,32 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), sel_(SEL_NONE), idx_(0)
PEIdent::PEIdent(const pform_name_t&that)
: path_(that)
{
}
PEIdent::PEIdent(perm_string s)
{
path_.push_back(name_component_t(s));
}
PEIdent::~PEIdent()
{
}
const hname_t& PEIdent::path() const
{
return path_;
}
/*
* An identifier can be in a constant expression if (and only if) it is
* a parameter.
*
* NOTE: This test does not work if the name is hierarchical!
*/
bool PEIdent::is_constant(Module*mod) const
{
if (mod == 0) return false;
/* This is a work-around for map not matching < even when
there is a perm_string operator that can do the comprare.
The real fix is to make the path_ carry perm_strings. */
perm_string tmp = perm_string::literal(path_.peek_name(0));
/* */
perm_string tmp = path_.back().name;
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
@@ -288,6 +300,10 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.39 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.38 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
+37 -25
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.87 2007/01/16 05:44:14 steve Exp $"
#ident "$Id: PExpr.h,v 1.90 2007/06/04 19:14:06 steve Exp $"
#endif
# include <string>
@@ -27,6 +27,7 @@
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
# include "pform_types.h"
class Design;
class Module;
@@ -124,7 +125,7 @@ class PExpr : public LineInfo {
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
@@ -150,7 +151,7 @@ class PEConcat : public PExpr {
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
@@ -221,7 +222,7 @@ class PEFNumber : public PExpr {
/* The eval_const method as applied to a floating point number
gets the *integer* value of the number. This accounts for
any rounding that is needed to get the value. */
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
@@ -247,9 +248,14 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(const hname_t&s);
explicit PEIdent(perm_string);
explicit PEIdent(const pform_name_t&);
~PEIdent();
// Add another name to the string of heirarchy that is the
// current identifier.
void append_name(perm_string);
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
@@ -284,9 +290,12 @@ class PEIdent : public PExpr {
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, NetScope*sc) const;
verinum* eval_const(Design*des, NetScope*sc) const;
const hname_t& path() const;
const pform_name_t& path() const { return path_; }
private:
pform_name_t path_;
private:
// Common functions to calculate parts of part/bit selects.
@@ -332,19 +341,9 @@ class PEIdent : public PExpr {
NetScope*scope,
NetESignal*net,
NetScope*found) const;
hname_t path_;
public:
// Use these to support part-select operators.
PExpr*msb_;
PExpr*lsb_;
enum { SEL_NONE, SEL_PART, SEL_IDX_UP, SEL_IDX_DO } sel_;
// If this is a reference to a memory/array, this is the index
// expression. If this is a reference to a vector, this is a
// bit select.
std::vector<PExpr*> idx_;
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
@@ -370,6 +369,7 @@ class PEIdent : public PExpr {
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
unsigned&midx, unsigned&lidx) const;
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
};
@@ -400,7 +400,7 @@ class PENumber : public PExpr {
NetScope*scope,
bool is_force) const;
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -439,7 +439,7 @@ class PEString : public PExpr {
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(const Design*, NetScope*) const;
verinum* eval_const(Design*, NetScope*) const;
virtual bool is_constant(Module*) const;
@@ -465,7 +465,7 @@ class PEUnary : public PExpr {
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -498,7 +498,7 @@ class PEBinary : public PExpr {
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
protected:
char op_;
@@ -606,7 +606,7 @@ class PETernary : public PExpr {
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
private:
PExpr*expr_;
@@ -621,8 +621,10 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
// Call of system function (name is not heirarchical)
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
~PECallFunction();
virtual void dump(ostream &) const;
@@ -638,7 +640,7 @@ class PECallFunction : public PExpr {
int expr_wid, bool sys_task_arg) const;
private:
hname_t path_;
pform_name_t path_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
@@ -655,6 +657,16 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.90 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.89 2007/06/04 02:19:07 steve
* Handle bit/part select of array words in nets.
*
* Revision 1.88 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.87 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
+4 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.cc,v 1.2 2007/03/05 05:59:10 steve Exp $"
#ident "$Id: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "PGenerate.h"
@@ -26,6 +26,7 @@
PGenerate::PGenerate(unsigned id)
: id_number(id)
{
parent = 0;
}
PGenerate::~PGenerate()
@@ -42,9 +43,9 @@ PWire* PGenerate::add_wire(PWire*wire)
return wire;
}
PWire* PGenerate::get_wire(const hname_t&name) const
PWire* PGenerate::get_wire(const pform_name_t&name) const
{
map<hname_t,PWire*>::const_iterator obj = wires.find(name);
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
if (obj == wires.end())
return 0;
else
+8 -4
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.h,v 1.2 2007/03/05 05:59:10 steve Exp $"
#ident "$Id: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "LineInfo.h"
@@ -27,6 +27,7 @@
# include "HName.h"
# include <list>
# include <map>
# include "pform_types.h"
class Design;
class NetScope;
@@ -59,9 +60,9 @@ class PGenerate : public LineInfo {
PExpr*loop_test;
PExpr*loop_step;
map<hname_t,PWire*>wires;
map<pform_name_t,PWire*>wires;
PWire* add_wire(PWire*);
PWire* get_wire(const hname_t&name) const;
PWire* get_wire(const pform_name_t&name) const;
list<PGate*> gates;
void add_gate(PGate*);
@@ -69,6 +70,9 @@ class PGenerate : public LineInfo {
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
list<PGenerate*> generates;
PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.
@@ -77,7 +81,7 @@ class PGenerate : public LineInfo {
bool elaborate_sig(Design*des) const;
bool elaborate(Design*des) const;
void dump(ostream&out) const;
void dump(ostream&out, unsigned indent) const;
private:
bool generate_scope_loop_(Design*des, NetScope*container);
+11 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2005 Stephen Williams ([email protected])
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
*
* 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,29 +17,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.cc,v 1.12 2007/01/16 05:44:14 steve Exp $"
#ident "$Id: PWire.cc,v 1.14 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
# include "PWire.h"
# include <assert.h>
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) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
PWire::PWire(char*n,
PWire::PWire(const pform_name_t&n,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt)
@@ -59,7 +44,7 @@ NetNet::Type PWire::get_wire_type() const
return type_;
}
const hname_t& PWire::path() const
const pform_name_t& PWire::path() const
{
return hname_;
}
@@ -160,6 +145,13 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
/*
* $Log: PWire.cc,v $
* Revision 1.14 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.13 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.12 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
+18 -48
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,13 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.19 2006/04/10 00:37:42 steve Exp $"
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
# include <map>
# include "svector.h"
# include "StringHeap.h"
#ifdef HAVE_IOSFWD
# include <iosfwd>
@@ -42,24 +43,21 @@ class Design;
* identifies a port by keeping it in its port list.
*
* The hname parameter to the constructor is a hierarchical name. It
* is an array of strings starting with the root, running towards
* the base name, and terminated by a null pointer. The environment
* allocates the memory for me.
* is the name of the wire within a module, so does not include the
* current scope or any instances. Modules contain all the wires, so
* from that perspective, sub-scopes within the module are a part of
* the wire name.
*/
class PWire : public LineInfo {
public:
PWire(const hname_t&hname,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
PWire(char*name,
PWire(const pform_name_t&hname,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
// Return a hierarchical name.
const hname_t&path() const;
const pform_name_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -83,10 +81,10 @@ class PWire : public LineInfo {
// Write myself to the specified stream.
void dump(ostream&out, unsigned ind=4) const;
void elaborate_sig(Design*, NetScope*scope) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const;
private:
hname_t hname_;
pform_name_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
ivl_variable_type_t data_type_;
@@ -110,6 +108,13 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.21 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.20 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.19 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
@@ -146,40 +151,5 @@ class PWire : public LineInfo {
*
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.9 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.8 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.7 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
* Revision 1.5 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
* Revision 1.4 1999/06/02 15:38:46 steve
* Line information with nets.
*
* Revision 1.3 1999/04/19 01:59:36 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.2 1998/11/23 00:20:22 steve
* NetAssign handles lvalues as pin links
* instead of a signal pointer,
* Wire attributes added,
* Ability to parse UDP descriptions added,
* XNF generates EXT records for signals with
* the PAD attribute.
*
* Revision 1.1 1998/11/03 23:28:55 steve
* Introduce verilog to CVS.
*
*/
#endif
+15 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -107,16 +107,22 @@ PBlock::~PBlock()
delete list_[idx];
}
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
}
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
: parms_(p)
{
path_.push_back(name_component_t(n));
}
PCallTask::~PCallTask()
{
}
const hname_t& PCallTask::path() const
const pform_name_t& PCallTask::path() const
{
return path_;
}
@@ -178,7 +184,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const hname_t&sc)
PDisable::PDisable(const pform_name_t&sc)
: scope_(sc)
{
}
@@ -273,7 +279,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const hname_t&e)
PTrigger::PTrigger(const pform_name_t&e)
: event_(e)
{
}
@@ -295,6 +301,10 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.30 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
+13 -8
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.h,v 1.43 2007/03/05 05:59:10 steve Exp $"
#ident "$Id: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
#endif
# include <string>
@@ -173,10 +173,11 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
~PCallTask();
const hname_t& path() const;
const pform_name_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -197,7 +198,7 @@ class PCallTask : public Statement {
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
hname_t path_;
pform_name_t path_;
svector<PExpr*> parms_;
};
@@ -296,14 +297,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement {
public:
explicit PDisable(const hname_t&sc);
explicit PDisable(const pform_name_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
hname_t scope_;
pform_name_t scope_;
};
/*
@@ -433,14 +434,14 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const hname_t&ev);
explicit PTrigger(const pform_name_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
hname_t event_;
pform_name_t event_;
};
class PWhile : public Statement {
@@ -460,6 +461,10 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.44 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.43 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
+6 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: _pli_types.h.in,v 1.7 2003/11/12 02:38:44 steve Exp $"
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
@@ -42,7 +42,7 @@ typedef int32_t PLI_INT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef signed char PLI_BYTE8;
typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
# define PLI_UINT64_FMT PRIu64
@@ -84,12 +84,15 @@ typedef signed int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef signed char PLI_BYTE8;
typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/*
* $Log: _pli_types.h.in,v $
* Revision 1.8 2007/06/05 21:32:30 steve
* More standard PLI_BYTE8.
*
* Revision 1.7 2003/11/12 02:38:44 steve
* Clean up manual definitions of PLI_UINT64_FMT.
*
Vendored
+3 -3
View File
@@ -14,7 +14,7 @@
AC_DEFUN([AX_CPP_IDENT],
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
[AC_TRY_COMPILE([
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
@@ -48,7 +48,7 @@ AC_DEFUN([AX_C_UNDERSCORES_LEADING],
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
AC_DEFINE(NEED_LU)
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
fi
])# AX_C_UNDERSCORES_LEADING
@@ -63,7 +63,7 @@ AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
if test $ax_cv_c_underscores_trailing = yes; then
AC_DEFINE(NEED_TU)
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
fi
])# AX_C_UNDERSCORES_TRAILING
+1 -1
View File
@@ -66,7 +66,7 @@ AC_TRY_LINK(
#include <sys/times.h>
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
do_times=yes
AC_DEFINE(HAVE_TIMES,1),
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
do_times=no
)
AC_MSG_RESULT($do_times)
+52 -25
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.174 2007/03/02 06:13:22 steve Exp $"
#ident "$Id: design_dump.cc,v 1.176 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -91,6 +91,25 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
return o;
}
static inline void dump_scope_path(ostream&o, const NetScope*scope)
{
if (const NetScope*parent = scope->parent()) {
dump_scope_path(o, parent);
o << ".";
}
const hname_t name = scope->fullname();
o << name.peek_name();
if (name.has_number())
o << "[" << name.peek_number() << "]";
}
ostream& operator <<(ostream&o, struct __ScopePathManip marg)
{
if (marg.scope != 0)
dump_scope_path(o, marg.scope);
return o;
}
void NetDelaySrc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "specify delay";
@@ -141,7 +160,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
}
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
o << " scope=" << scope()->name();
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count()
@@ -264,7 +283,7 @@ void NetConcat::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetConcat: "
<< name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< " width=" << width_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -288,7 +307,7 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
<< " width=" << width_ << " swidth=" << swidth_ << " size=" << size_
<< " scope=" << scope()->name() << endl;
<< " scope=" << scope_path(scope()) << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -296,7 +315,7 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetBUFZ: " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ") width=" << width() << endl;
dump_node_pins(o, ind+4);
@@ -324,7 +343,7 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
void NetFF::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_FF: " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< " aset_value=" << aset_value_ << endl;
dump_node_pins(o, ind+4);
@@ -399,7 +418,7 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< endl;
dump_node_pins(o, ind+4);
@@ -478,7 +497,7 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< endl;
dump_node_pins(o, ind+4);
@@ -494,7 +513,7 @@ void NetSysFunc::dump_node(ostream&o, unsigned ind) const
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << def_->name() << "(";
o << setw(ind) << "" << scope_path(def_) << "(";
o << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -502,7 +521,7 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
void NetTaskDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "task " << name_ << ";" << endl;
o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
o << setw(ind+4) << "";
@@ -544,11 +563,11 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
switch (type_) {
case NetProcTop::KINITIAL:
o << "initial /* " << get_line() << " in "
<< scope_->name() << " */" << endl;
<< scope_path(scope_) << " */" << endl;
break;
case NetProcTop::KALWAYS:
o << "always /* " << get_line() << " in "
<< scope_->name() << " */" << endl;
<< scope_path(scope_) << " */" << endl;
break;
}
@@ -630,7 +649,7 @@ void NetBlock::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_;
if (subscope_)
o << " : " << subscope_->name();
o << " : " << scope_path(subscope_);
o << endl;
if (last_) {
@@ -707,7 +726,7 @@ void NetDeassign::dump(ostream&o, unsigned ind) const
void NetDisable::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "disable " << target_->name() << "; "
o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
<< "/* " << get_line() << " */" << endl;
}
@@ -726,7 +745,7 @@ void NetEvProbe::dump_node(ostream&o, unsigned ind) const
o << "negedge ";
break;
}
o << setw(ind) << "" << "-> " << event_->full_name() << "; " << endl;
o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -742,10 +761,10 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
o << setw(ind) <<"" << "@(";
if (nevents() > 0)
o << event(0)->full_name();
o << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << event(idx)->full_name();
o << " or " << event(idx)->name();
o << ") // " << get_line() << endl;
@@ -770,7 +789,7 @@ void NetForever::dump(ostream&o, unsigned ind) const
void NetFuncDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "function " << scope_->name() << endl;
o << setw(ind) << "" << "function " << scope_path(scope_) << endl;
if (result_sig_)
o << setw(ind+2) << "" << "Return signal: "
<< result_sig_->name() << endl;
@@ -813,7 +832,7 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const
{
/* This is a constructed hierarchical name. */
o << name();
o << scope_path(this);
switch (type_) {
case BEGIN_END:
@@ -871,7 +890,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */
{
map<hname_t,NetExpr*>::const_iterator pp;
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@@ -882,7 +901,8 @@ void NetScope::dump(ostream&o) const
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
<< cur->nprobe() << " // " << cur->get_line() << endl;
<< cur->nprobe() << " scope=" << scope_path(cur->scope())
<< " // " << cur->get_line() << endl;
}
// Dump the signals,
@@ -956,7 +976,7 @@ void NetSTask::dump(ostream&o, unsigned ind) const
void NetUTask::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << task_->name() << ";" << endl;
o << setw(ind) << "" << scope_path(task_) << ";" << endl;
}
void NetWhile::dump(ostream&o, unsigned ind) const
@@ -1091,7 +1111,7 @@ void NetEEvent::dump(ostream&o) const
void NetEScope::dump(ostream&o) const
{
o << "<scope=" << scope_->name() << ">";
o << "<scope=" << scope_path(scope_) << ">";
}
void NetESelect::dump(ostream&o) const
@@ -1135,7 +1155,7 @@ void NetESignal::dump(ostream&o) const
void NetEParam::dump(ostream&o) const
{
if (scope_ != 0)
o << "<" << scope_->name() << "." << name_ << ">";
o << "<" << scope_path(scope_) << "." << name_ << ">";
else if (name_)
o << "<" << name_ << ">";
else
@@ -1150,7 +1170,7 @@ void NetETernary::dump(ostream&o) const
void NetEUFunc::dump(ostream&o) const
{
o << name() << "(";
o << func_->basename() << "(";
if (parms_.count() > 0) {
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
@@ -1205,6 +1225,13 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.176 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.175 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.174 2007/03/02 06:13:22 steve
* Add support for edge sensitive spec paths.
*
+3 -1
View File
@@ -1,4 +1,4 @@
.TH iverilog 1 "$Date: 2007/03/22 16:08:18 $" Version "$Date: 2007/03/22 16:08:18 $"
.TH iverilog 1 "$Date: 2007/06/05 01:56:12 $" Version "$Date: 2007/06/05 01:56:12 $"
.SH NAME
iverilog - Icarus Verilog compiler
@@ -89,6 +89,8 @@ leading or trailing space.
Add this module to the list of VPI modules to be loaded by the
simulation. Many modules can be specified, and all will be loaded, in
the order specified. The system module is implicit and always included.
If a System Function Table file (<module>.sft) exists for the module it
will be loaded automatically.
.TP 8
.B -N\fIpath\fP
This is used for debugging the compiler proper. Dump the final netlist
+19 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.75 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: main.c,v 1.76 2007/06/05 01:56:12 steve Exp $"
#endif
# include "config.h"
@@ -455,6 +455,20 @@ int process_generation(const char*name)
return 0;
}
/*
* If it exists add the SFT file for the given module.
*/
void add_sft_file(const char *module)
{
char *file;
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
sprintf(file, "%s%c%s.sft", base, sep, module);
if (access(file, R_OK) == 0)
fprintf(iconfig_file, "sys_func:%s\n", file);
free(file);
}
int main(int argc, char **argv)
{
char*cmd;
@@ -598,6 +612,7 @@ int main(int argc, char **argv)
case 'm':
fprintf(iconfig_file, "module:%s\n", optarg);
add_sft_file(optarg);
break;
case 'N':
@@ -787,6 +802,9 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.76 2007/06/05 01:56:12 steve
* Bring in .SFT file automatically if -m used.
*
* Revision 1.75 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
+156 -94
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_expr.cc,v 1.124 2007/04/01 05:28:26 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.126 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -322,7 +322,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
not lead to executable code but takes the single parameter
and makes it into a signed expression. No bits are changed,
it just changes the interpretation. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if (strcmp(peek_tail_name(path_), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
@@ -336,7 +336,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return sub;
}
/* add $unsigned to match $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if (strcmp(peek_tail_name(path_), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
@@ -354,8 +354,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
the bit width of the sub-expression. The value of the
sub-expression is not used, so the expression itself can be
deleted. */
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
if ((strcmp(peek_tail_name(path_), "$sizeof") == 0)
|| (strcmp(peek_tail_name(path_), "$bits") == 0)) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $bits() function "
<< "takes exactly one(1) argument." << endl;
@@ -363,7 +363,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return 0;
}
if (strcmp(path_.peek_name(0), "$sizeof") == 0)
if (strcmp(peek_tail_name(path_), "$sizeof") == 0)
cerr << get_line() << ": warning: $sizeof is deprecated."
<< " Use $bits() instead." << endl;
@@ -382,7 +382,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
a single bit flag -- 1 if the expression is signed, 0
otherwise. The subexpression is elaborated but not
evaluated. */
if (strcmp(path_.peek_name(0), "$is_signed") == 0) {
if (strcmp(peek_tail_name(path_), "$is_signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $is_signed() function "
<< "takes exactly one(1) argument." << endl;
@@ -405,7 +405,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
/* Get the return type of the system function by looking it up
in the sfunc_table. */
const struct sfunc_return_type*sfunc_info
= lookup_sys_func(path_.peek_name(0));
= lookup_sys_func(peek_tail_name(path_));
ivl_variable_type_t sfunc_type = sfunc_info->type;
unsigned wid = sfunc_info->wid;
@@ -423,7 +423,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
if ((nparms == 1) && (parms_[0] == 0))
nparms = 0;
NetESFunc*fun = new NetESFunc(path_.peek_name(0), sfunc_type,
NetESFunc*fun = new NetESFunc(peek_tail_name(path_), sfunc_type,
wid, nparms);
if (sfunc_info->signed_flag)
fun->cast_signed(true);
@@ -455,7 +455,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
if (missing_parms > 0) {
cerr << get_line() << ": error: The function "
<< path_.peek_name(0)
<< peek_tail_name(path_)
<< " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
@@ -468,13 +468,13 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool) const
{
if (path_.peek_name(0)[0] == '$')
if (peek_tail_name(path_)[0] == '$')
return elaborate_sfunc_(des, scope);
NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) {
cerr << get_line() << ": error: No function " << path_ <<
" in this context (" << scope->name() << ")." << endl;
" in this context (" << scope_path(scope) << ")." << endl;
des->errors += 1;
return 0;
}
@@ -538,7 +538,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << path_
<< " in " << def->name() << "." << endl;
<< " in " << dscope->basename() << "." << endl;
des->errors += 1;
return 0;
}
@@ -620,33 +620,38 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const
bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
long&msb, long&lsb) const
{
assert(lsb_ != 0);
assert(msb_ != 0);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.sel == index_component_t::SEL_PART);
ivl_assert(*this, index_tail.msb && index_tail.lsb);
/* This handles part selects. In this case, there are
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
NetExpr*lsb_ex = elab_and_eval(des, scope, lsb_, -1);
NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
if (lsb_c == 0) {
cerr << lsb_->get_line() << ": error: "
cerr << index_tail.lsb->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << lsb_->get_line() << ": : This lsb expression "
"violates the rule: " << *lsb_ << endl;
cerr << index_tail.lsb->get_line() << ": : "
"This lsb expression violates the rule: "
<< *index_tail.lsb << endl;
des->errors += 1;
return false;
}
NetExpr*msb_ex = elab_and_eval(des, scope, msb_, -1);
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, -1);
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) {
cerr << msb_->get_line() << ": error: "
cerr << index_tail.msb->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << msb_->get_line() << ": : This msb expression "
"violates the rule: " << *msb_ << endl;
cerr << index_tail.msb->get_line() << ": : This msb expression "
"violates the rule: " << *index_tail.msb << endl;
des->errors += 1;
return false;
}
@@ -662,13 +667,18 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
unsigned long&wid) const
{
assert(lsb_);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.lsb && index_tail.msb);
bool flag = true;
/* Calculate the width expression (in the lsb_ position)
first. If the expression is not constant, error but guess 1
so we can keep going and find more errors. */
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
if (wid_c == 0) {
@@ -695,30 +705,36 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
const NetExpr*ex1, *ex2;
symbol_search(des, scope, path_,
net, par, eve,
ex1, ex2);
symbol_search(des, scope, path_, net, par, eve, ex1, ex2);
if (net != 0) {
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
unsigned use_width = net->vector_width();
switch (sel_) {
case SEL_NONE:
switch (use_sel) {
case index_component_t::SEL_NONE:
break;
case SEL_PART:
case index_component_t::SEL_PART:
{ long msb, lsb;
calculate_parts_(des, scope, msb, lsb);
use_width = 1 + ((msb>lsb)? (msb-lsb) : (lsb-msb));
break;
}
case SEL_IDX_UP:
case SEL_IDX_DO:
case index_component_t::SEL_IDX_UP:
case index_component_t::SEL_IDX_DO:
{ unsigned long tmp = 0;
calculate_up_do_width_(des, scope, tmp);
use_width = tmp;
break;
}
case index_component_t::SEL_BIT:
use_width = 1;
break;
default:
assert(0);
ivl_assert(*this, 0);
}
return use_width;
}
@@ -774,9 +790,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// Hmm... maybe this is a genvar? This is only possible while
// processing generate blocks, but then the genvar_tmp will be
// set in the scope.
if (path_.component_count() == 1
if (path_.size() == 1
&& scope->genvar_tmp.str()
&& strcmp(path_.peek_name(0), scope->genvar_tmp) == 0) {
&& strcmp(peek_tail_name(path_), scope->genvar_tmp) == 0) {
verinum val (scope->genvar_tmp_val);
NetEConst*tmp = new NetEConst(val);
tmp->set_line(*this);
@@ -790,8 +806,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
if (gn_specify_blocks_flag) {
map<perm_string,NetScope::spec_val_t>::const_iterator specp;
perm_string key = perm_string::literal(path_.peek_name(0));
if (path_.component_count() == 1
perm_string key = peek_tail_name(path_);
if (path_.size() == 1
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
NetScope::spec_val_t value = (*specp).second;
NetExpr*tmp = 0;
@@ -814,22 +830,26 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// Finally, if this is a scope name, then return that. Look
// first to see if this is a name of a local scope. Failing
// that, search globally for a hierarchical name.
if ((path_.peek_name(1) == 0))
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
if ((path_.size() == 1)) {
hname_t use_name ( peek_tail_name(path_) );
if (NetScope*nsc = scope->child(use_name)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
}
}
list<hname_t> spath = eval_scope_path(des, scope, path_);
// Try full hierarchical scope name.
if (NetScope*nsc = des->find_scope(path_)) {
if (NetScope*nsc = des->find_scope(spath)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
}
// Try relative scope name.
if (NetScope*nsc = des->find_scope(scope, path_)) {
if (NetScope*nsc = des->find_scope(scope, spath)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
@@ -837,7 +857,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// I cannot interpret this identifier. Error message.
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
"`" << path_ << "' in `" << scope->name() << "'" << endl;
"`" << path_ << "' in `" << scope_path(scope) << "'" << endl;
des->errors += 1;
return 0;
}
@@ -854,13 +874,18 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
const NetExpr*par_msb,
const NetExpr*par_lsb) const
{
NetExpr*tmp;
NetExpr*tmp = par->dup_expr();
tmp = par->dup_expr();
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
if (sel_ == SEL_PART) {
assert(msb_ && lsb_);
assert(idx_.empty());
if (use_sel == index_component_t::SEL_PART) {
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb);
ivl_assert(*this, index_tail.lsb);
/* If the identifier has a part select, we support
it by pulling the right bits out and making a
@@ -868,8 +893,8 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
lsb of a parameter is 0 and the msb is the
width of the parameter. */
verinum*lsn = lsb_->eval_const(des, scope);
verinum*msn = msb_->eval_const(des, scope);
verinum*lsn = index_tail.lsb->eval_const(des, scope);
verinum*msn = index_tail.msb->eval_const(des, scope);
if ((lsn == 0) || (msn == 0)) {
cerr << get_line() << ": error: "
"Part select expressions must be "
@@ -926,17 +951,19 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
delete tmp;
tmp = new NetEConst(result);
} else if (sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO) {
assert(msb_);
assert(lsb_);
assert(idx_.empty());
} else if (use_sel == index_component_t::SEL_IDX_UP || use_sel == index_component_t::SEL_IDX_DO) {
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb);
ivl_assert(*this, index_tail.lsb);
/* Get and evaluate the width of the index
select. This must be constant. */
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_, -1);
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) {
cerr << lsb_->get_line() << ": error: "
cerr << index_tail.lsb->get_line() << ": error: "
<< "Second expression of indexed part select "
<< "most be constant." << endl;
des->errors += 1;
@@ -945,12 +972,12 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
unsigned wid = wid_ec->value().as_ulong();
NetExpr*idx_ex = elab_and_eval(des, scope, msb_, -1);
NetExpr*idx_ex = elab_and_eval(des, scope, index_tail.msb, -1);
if (idx_ex == 0) {
return 0;
}
if (sel_ == SEL_IDX_DO && wid > 1) {
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1) {
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
}
@@ -959,16 +986,16 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
tmp = new NetESelect(tmp, idx_ex, wid);
} else if (!idx_.empty()) {
assert(!msb_);
assert(!lsb_);
assert(idx_.size() == 1);
assert(sel_ == SEL_NONE);
} else if (use_sel == index_component_t::SEL_BIT) {
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb);
ivl_assert(*this, !index_tail.lsb);
/* Handle the case where a parameter has a bit
select attached to it. Generate a NetESelect
object to select the bit as desired. */
NetExpr*mtmp = idx_[0]->elaborate_expr(des, scope, -1,false);
NetExpr*mtmp = index_tail.msb->elaborate_expr(des, scope, -1,false);
if (! dynamic_cast<NetEConst*>(mtmp)) {
NetExpr*re = mtmp->eval_tree();
if (re) {
@@ -1045,8 +1072,7 @@ NetExpr* PEIdent::elaborate_expr_param(Design*des,
NetEConstParam if possible. */
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
if (ctmp != 0) {
perm_string name
= lex_strings.make(path_.peek_tail_name());
perm_string name = peek_tail_name(path_);
NetEConstParam*ptmp
= new NetEConstParam(found_in, name, ctmp->value());
delete tmp;
@@ -1065,17 +1091,32 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
NetNet*net, NetScope*found_in,
bool sys_task_arg) const
{
if (idx_.empty() && !sys_task_arg) {
const name_component_t&name_tail = path_.back();
if (name_tail.index.empty() && !sys_task_arg) {
cerr << get_line() << ": error: Array " << path()
<< " Needs an array index here." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, sys_task_arg || !idx_.empty());
NetExpr*word_index = idx_.empty()
index_component_t index_front;
if (! name_tail.index.empty()) {
index_front = name_tail.index.front();
ivl_assert(*this, index_front.sel != index_component_t::SEL_NONE);
if (index_front.sel != index_component_t::SEL_BIT) {
cerr << get_line() << ": error: Array " << path_
<< " cannot be indexed by a range." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, index_front.msb);
ivl_assert(*this, !index_front.lsb);
}
NetExpr*word_index = index_front.sel == index_component_t::SEL_NONE
? 0
: elab_and_eval(des, scope, idx_[0], -1);
: elab_and_eval(des, scope, index_front.msb, -1);
if (word_index == 0 && !sys_task_arg)
return 0;
@@ -1106,15 +1147,22 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
NetESignal*res = new NetESignal(net, word_index);
res->set_line(*this);
if (sel_ == SEL_PART)
// Detect that the word has a part select as well.
index_component_t::ctype_t word_sel = index_component_t::SEL_NONE;
if (name_tail.index.size() > 1)
word_sel = name_tail.index.back().sel;
if (word_sel == index_component_t::SEL_PART)
return elaborate_expr_net_part_(des, scope, res, found_in);
if (sel_ == SEL_IDX_UP)
if (word_sel == index_component_t::SEL_IDX_UP)
return elaborate_expr_net_idx_up_(des, scope, res, found_in);
if (sel_ == SEL_IDX_DO)
if (word_sel == index_component_t::SEL_IDX_DO)
return elaborate_expr_net_idx_do_(des, scope, res, found_in);
ivl_assert(*this, word_sel == index_component_t::SEL_NONE);
return res;
}
@@ -1125,7 +1173,6 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
NetESignal*net, NetScope*found_in) const
{
long msv, lsv;
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
bool flag = calculate_parts_(des, scope, msv, lsv);
if (!flag)
return 0;
@@ -1183,12 +1230,14 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
NetESignal*net, NetScope*found_in) const
{
assert(lsb_ != 0);
assert(msb_ != 0);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.lsb != 0);
ivl_assert(*this, index_tail.msb != 0);
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid);
@@ -1235,12 +1284,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
NetESignal*net, NetScope*found_in)const
{
assert(lsb_ != 0);
assert(msb_ != 0);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, ! name_tail.index.empty());
ivl_assert(*this, (idx_.empty()&& !net->word_index()) || (!idx_.empty()&& net->word_index()));
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.lsb != 0);
ivl_assert(*this, index_tail.msb != 0);
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid);
@@ -1284,11 +1335,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
NetESignal*net, NetScope*found_in) const
{
assert(msb_ == 0);
assert(lsb_ == 0);
assert(idx_.size() == 1);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
NetExpr*ex = elab_and_eval(des, scope, idx_[0], -1);
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
NetExpr*ex = elab_and_eval(des, scope, index_tail.msb, -1);
// If the bit select is constant, then treat it similar
// to the part select, so that I save the effort of
@@ -1358,29 +1412,30 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
NetESignal*node = new NetESignal(net);
node->set_line(*this);
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (! path_.back().index.empty())
use_sel = path_.back().index.back().sel;
// If this is a part select of a signal, then make a new
// temporary signal that is connected to just the
// selected bits. The lsb_ and msb_ expressions are from
// the foo[msb:lsb] expression in the original.
if (sel_ == SEL_PART)
if (use_sel == index_component_t::SEL_PART)
return elaborate_expr_net_part_(des, scope, node, found_in);
if (sel_ == SEL_IDX_UP)
if (use_sel == index_component_t::SEL_IDX_UP)
return elaborate_expr_net_idx_up_(des, scope, node, found_in);
if (sel_ == SEL_IDX_DO)
if (use_sel == index_component_t::SEL_IDX_DO)
return elaborate_expr_net_idx_do_(des, scope, node, found_in);
if (!idx_.empty())
if (use_sel == index_component_t::SEL_BIT)
return elaborate_expr_net_bit_(des, scope, node, found_in);
// It's not anything else, so this must be a simple identifier
// expression with no part or bit select. Return the signal
// itself as the expression.
assert(sel_ == SEL_NONE);
assert(msb_ == 0);
assert(lsb_ == 0);
assert(idx_.empty());
assert(use_sel == index_component_t::SEL_NONE);
return node;
}
@@ -1633,6 +1688,13 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
/*
* $Log: elab_expr.cc,v $
* Revision 1.126 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.125 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.124 2007/04/01 05:28:26 steve
* Get offsets into indexed part selects correct.
*
+57 -25
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_lval.cc,v 1.42 2007/03/14 05:06:49 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.44 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -156,18 +156,24 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
symbol_search(des, scope, path_, reg, par, eve);
if (reg == 0) {
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
<< path_ << "'' in ``" << scope_path(scope) <<
"''" << endl;
des->errors += 1;
return 0;
}
assert(reg);
ivl_assert(*this, reg);
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
// This is the special case that the l-value is an entire
// memory. This is, in fact, an error.
if (reg->array_dimensions() > 0 && idx_.size() == 0) {
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
cerr << get_line() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
des->errors += 1;
@@ -177,19 +183,19 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
if (sel_ == SEL_PART) {
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
return lv;
}
if (sel_ == SEL_IDX_UP) {
if (use_sel == index_component_t::SEL_IDX_UP) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_up_(des, scope, lv);
return lv;
}
if (sel_ == SEL_IDX_DO) {
if (use_sel == index_component_t::SEL_IDX_DO) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
@@ -200,7 +206,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_line() << ": error: " << path_ <<
" is not a valid l-value in " << scope->name() <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
@@ -208,12 +214,14 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0;
}
ivl_assert(*this, msb_ == 0);
ivl_assert(*this, lsb_ == 0);
long msb, lsb;
NetExpr*mux;
if (! idx_.empty()) {
if (use_sel == index_component_t::SEL_BIT) {
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
@@ -221,9 +229,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
expression it not constant, then return the
expression as a mux. */
ivl_assert(*this, idx_.size() == 1);
NetExpr*index_expr = elab_and_eval(des, scope, idx_[0], -1);
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
msb = index_con->value().as_long();
@@ -311,9 +317,15 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
NetScope*scope,
NetNet*reg) const
{
assert(idx_.size() == 1);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
NetExpr*word = elab_and_eval(des, scope, idx_[0], -1);
const index_component_t&index_head = name_tail.index.front();
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
// If there is a non-zero base to the memory, then build an
// expression to calculate the canonical address.
@@ -348,13 +360,17 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
/* An array word may also have part selects applied to them. */
if (sel_ == SEL_PART)
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel;
if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv);
if (sel_ == SEL_IDX_UP)
if (use_sel == index_component_t::SEL_IDX_UP)
elaborate_lval_net_idx_up_(des, scope, lv);
if (sel_ == SEL_IDX_DO)
if (use_sel == index_component_t::SEL_IDX_DO)
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
@@ -417,15 +433,19 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
assert(lsb_);
assert(msb_);
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb != 0);
NetNet*reg = lv->sig();
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
" is not a reg/integer/time in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
@@ -436,7 +456,7 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, msb_, -1);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
@@ -457,8 +477,13 @@ bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
assert(lsb_);
assert(msb_);
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb != 0);
cerr << get_line() << ": internal error: don't know how to "
"deal with SEL_IDX_DO in lval?" << endl;
des->errors += 1;
@@ -475,6 +500,13 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
/*
* $Log: elab_lval.cc,v $
* Revision 1.44 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.43 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.42 2007/03/14 05:06:49 steve
* Replace some asserts with ivl_asserts.
*
+171 -81
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.203 2007/04/18 01:40:49 steve Exp $"
#ident "$Id: elab_net.cc,v 1.207 2007/06/12 04:05:45 steve Exp $"
#endif
# include "config.h"
@@ -1230,7 +1230,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
unsigned errors = 0;
unsigned func_pins = 0;
if (path_.peek_name(0)[0] == '$')
if (path_.front().name[0] == '$')
return elaborate_net_sfunc_(des, scope,
width, rise, fall, decay,
drive0, drive1);
@@ -1240,7 +1240,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) {
cerr << get_line() << ": error: No function " << path_ <<
" in this context (" << scope->name() << ")." << endl;
" in this context (" << scope_path(scope) << ")." << endl;
des->errors += 1;
return 0;
}
@@ -1320,11 +1320,13 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
Link::strength_t drive0,
Link::strength_t drive1) const
{
perm_string name = peek_tail_name(path_);
/* Handle the special case that the function call is to
$signed. This takes a single expression argument, and
forces it to be a signed result. Otherwise, it is as if the
$signed did not exist. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if (strcmp(name, "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
@@ -1340,7 +1342,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
}
/* handle $unsigned like $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if (strcmp(name, "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
@@ -1355,11 +1357,11 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
return sub;
}
const struct sfunc_return_type*def = lookup_sys_func(path_.peek_name(0));
const struct sfunc_return_type*def = lookup_sys_func(name);
if (def == 0) {
cerr << get_line() << ": error: System function "
<< path_.peek_name(0) << " not defined." << endl;
<< peek_tail_name(path_) << " not defined." << endl;
des->errors += 1;
return 0;
}
@@ -1545,15 +1547,19 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
Link::strength_t drive0,
Link::strength_t drive1) const
{
assert(msb_ == 0);
assert(lsb_ == 0);
assert(idx_.size() == 1);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
/* Elaborate the selector. */
NetNet*sel;
if (sig->msb() < sig->lsb()) {
NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1, false);
NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1, false);
sel_expr = make_sub_expr(sig->lsb(), sel_expr);
if (NetExpr*tmp = sel_expr->eval_tree()) {
delete sel_expr;
@@ -1563,7 +1569,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
sel = sel_expr->synthesize(des);
} else if (sig->lsb() != 0) {
NetExpr*sel_expr = idx_[0]->elaborate_expr(des, scope, -1,false);
NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1,false);
sel_expr = make_add_expr(sel_expr, - sig->lsb());
if (NetExpr*tmp = sel_expr->eval_tree()) {
delete sel_expr;
@@ -1573,7 +1579,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
sel = sel_expr->synthesize(des);
} else {
sel = idx_[0]->elaborate_net(des, scope, 0, 0, 0, 0);
sel = index_tail.msb->elaborate_net(des, scope, 0, 0, 0, 0);
}
if (debug_elaborate) {
@@ -1604,10 +1610,12 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
Link::strength_t drive0,
Link::strength_t drive1) const
{
assert(scope);
ivl_assert(*this, scope);
const name_component_t&name_tail = path_.back();
NetNet* sig = 0;
const NetExpr*par = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, sig, par, eve);
@@ -1646,15 +1654,16 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
/* Check for the error case that the name is not found, and it
is hierarchical. We can't just create a name in another
scope, it's just not allowed. */
if (sig == 0 && path_.component_count() != 1) {
if (sig == 0 && path_.size() != 1) {
cerr << get_line() << ": error: The hierarchical name "
<< path_ << " is undefined in "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
hname_t tmp_path = path_;
delete[] tmp_path.remove_tail_name();
pform_name_t tmp_path = path_;
tmp_path.pop_back();
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
list<hname_t> stmp_path = eval_scope_path(des, scope, tmp_path);
NetScope*tmp_scope = des->find_scope(scope, stmp_path);
if (tmp_scope == 0) {
cerr << get_line() << ": : I can't even find "
<< "the scope " << tmp_path << "." << endl;
@@ -1667,28 +1676,28 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
/* Fallback, this may be an implicitly declared net. */
if (sig == 0) {
NetNet::Type nettype = scope->default_nettype();
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
sig = new NetNet(scope, name_tail.name,
nettype, 1);
sig->data_type(IVL_VT_LOGIC);
if (error_implicit || (nettype == NetNet::NONE)) {
cerr << get_line() << ": error: "
<< scope->name() << "." << path_.peek_name(0)
<< scope_path(scope) << "." << name_tail.name
<< " not defined in this scope." << endl;
des->errors += 1;
} else if (warn_implicit) {
cerr << get_line() << ": warning: implicit "
"definition of wire " << scope->name()
<< "." << path_.peek_name(0) << "." << endl;
"definition of wire " << scope_path(scope)
<< "." << name_tail.name << "." << endl;
}
}
assert(sig);
ivl_assert(*this, sig);
/* Handle the case that this is an array elsewhere. */
if (sig->array_dimensions() > 0) {
if (idx_.size() == 0) {
if (name_tail.index.size() == 0) {
cerr << get_line() << ": error: Array " << sig->name()
<< " cannot be used here without an index." << endl;
des->errors += 1;
@@ -1700,14 +1709,16 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
drive0, drive1);
}
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
/* Catch the case of a non-constant bit select. That should be
handled elsewhere. */
if (! idx_.empty()) {
assert(msb_ == 0);
assert(lsb_ == 0);
assert(idx_.size() == 1);
if (use_sel == index_component_t::SEL_BIT) {
const index_component_t&index_tail = name_tail.index.back();
verinum*mval = idx_[0]->eval_const(des, scope);
verinum*mval = index_tail.msb->eval_const(des, scope);
if (mval == 0) {
return elaborate_net_bitmux_(des, scope, sig, rise,
fall, decay, drive0, drive1);
@@ -1747,6 +1758,45 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
return sig;
}
NetNet* PEIdent::process_select_(Design*des, NetScope*scope,
NetNet*sig) const
{
// If there are more index items then there are array
// dimensions, then treat them as word part selects. For
// example, if this is a memory array, then array dimensions
// is 1 and
unsigned midx, lidx;
if (! eval_part_select_(des, scope, sig, midx, lidx))
return sig;
unsigned part_count = midx-lidx+1;
// Maybe this is a full-width constant part select? If
// so, do nothing.
if (part_count == sig->vector_width())
return sig;
if (debug_elaborate) {
cerr << get_line() << ": debug: Elaborate part select"
<< " of word from " << sig->name() << "[base="<<lidx
<< " wid=" << part_count << "]" << endl;
}
NetPartSelect*ps = new NetPartSelect(sig, lidx, part_count,
NetPartSelect::VP);
ps->set_line(*sig);
des->add_node(ps);
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));
return tmp;
}
NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
@@ -1755,9 +1805,18 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
Link::strength_t drive0,
Link::strength_t drive1) const
{
ivl_assert(*this, idx_.size() >= 1);
const name_component_t&name_tail = path_.back();
ivl_assert(*this, name_tail.index.size() >= 1);
const index_component_t&index_head = name_tail.index.front();
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
NetExpr*index_ex = elab_and_eval(des, scope, idx_[0], -1);
if (debug_elaborate)
cerr << get_line() << ": debug: elaborate array "
<< name_tail.name << " with index " << index_head << endl;
NetExpr*index_ex = elab_and_eval(des, scope, index_head.msb, -1);
if (index_ex == 0)
return 0;
@@ -1796,6 +1855,12 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
tmp->local_flag(true);
tmp->data_type(sig->data_type());
connect(tmp->pin(0), sig->pin(index));
// If there are more indices then needed to get to the
// word, then there is a part/bit select for the word.
if (name_tail.index.size() > sig->array_dimensions())
tmp = process_select_(des, scope, tmp);
return tmp;
}
@@ -1820,7 +1885,12 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
tmp->local_flag(true);
tmp->data_type(sig->data_type());
connect(tmp->pin(0), mux->pin_Result());
#if 0
// If there are more index items then there are array
// dimensions, then treat them as word part selects. For
// example, if this is a memory array, then array dimensions
// is 1 and
unsigned midx, lidx;
if (eval_part_select_(des, scope, sig, midx, lidx)) do {
@@ -1850,7 +1920,11 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
tmp = tmp2;
} while (0);
#else
if (name_tail.index.size() > sig->array_dimensions())
tmp = process_select_(des, scope, sig);
#endif
return tmp;
}
@@ -2006,15 +2080,15 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
NetNet*sig = 0;
if (!error_implicit && nettype!=NetNet::NONE) {
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1);
/* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC);
if (warn_implicit) {
cerr << get_line() << ": warning: implicit "
"definition of wire logic " << scope->name()
<< "." << path_.peek_name(0) << "." << endl;
"definition of wire logic " << scope_path(scope)
<< "." << peek_tail_name(path_) << "." << endl;
}
} else {
@@ -2037,20 +2111,30 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
unsigned&midx, unsigned&lidx) const
{
switch (sel_) {
const name_component_t&name_tail = path_.back();
// Only treat as part/bit selects any index that is beyond the
// word selects for an array. This is not an array, then
// dimensions==0 and any index is treated as a select.
if (name_tail.index.size() <= sig->array_dimensions()) {
midx = sig->vector_width()-1;
lidx = 0;
return true;
}
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
switch (index_tail.sel) {
default:
cerr << get_line() << ": internal error: "
<< "Unexpected sel_ value = " << sel_ << endl;
assert(0);
<< "Unexpected sel_ value = " << index_tail.sel << endl;
ivl_assert(*this, 0);
break;
case PEIdent::SEL_IDX_DO:
case PEIdent::SEL_IDX_UP: {
assert(msb_);
assert(lsb_);
assert(idx_.size() == sig->array_dimensions());
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1);
case index_component_t::SEL_IDX_DO:
case index_component_t::SEL_IDX_UP: {
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp);
@@ -2058,14 +2142,14 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
tmp_ex = elab_and_eval(des, scope, lsb_, -1);
tmp_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp);
long wid = tmp->value().as_long();
delete tmp_ex;
if (sel_ == PEIdent::SEL_IDX_UP)
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(midx_val+wid-1);
else
lidx = sig->sb_to_idx(midx_val-wid+1);
@@ -2079,12 +2163,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
break;
}
case PEIdent::SEL_PART: {
assert(msb_);
assert(lsb_);
assert(idx_.size() == sig->array_dimensions());
case index_component_t::SEL_PART: {
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_, -1);
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp);
@@ -2092,12 +2173,12 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
tmp_ex = elab_and_eval(des, scope, lsb_, -1);
tmp_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "lsb expression is not constant?: "
<< *tmp_ex << ", " << *lsb_ << endl;
<< *tmp_ex << ", " << *index_tail.lsb << endl;
}
assert(tmp);
@@ -2131,19 +2212,17 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
break;
}
case PEIdent::SEL_NONE:
if (idx_.size() > sig->array_dimensions()) {
unsigned a_dims = sig->array_dimensions();
assert(msb_ == 0);
assert(lsb_ == 0);
assert(idx_.size() == a_dims+1);
verinum*mval = idx_[a_dims]->eval_const(des, scope);
case index_component_t::SEL_BIT:
if (name_tail.index.size() > sig->array_dimensions()) {
verinum*mval = index_tail.msb->eval_const(des, scope);
if (mval == 0) {
cerr << get_line() << ": error: Index of " << path_ <<
" needs to be constant in this context." <<
endl;
cerr << get_line() << ": : Index expression is: "
<< *(idx_[0]) << endl;
<< *index_tail.msb << endl;
cerr << get_line() << ": : Context scope is: "
<< scope_path(scope) << endl;
des->errors += 1;
return false;
}
@@ -2160,17 +2239,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
lidx = midx;
} else {
if (msb_ || lsb_) {
cerr << get_line() << ": internal error: "
<< "Unexpected msb_/lsb_ values?" << endl;
if (msb_)
cerr << get_line() << " : "
<< *msb_ << endl;
if (lsb_)
cerr << get_line() << " : "
<< *lsb_ << endl;
}
assert(msb_ == 0 && lsb_ == 0);
cerr << get_line() << ": internal error: "
<< "Bit select " << path_ << endl;
ivl_assert(*this, 0);
midx = sig->vector_width() - 1;
lidx = 0;
}
@@ -2245,10 +2316,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
// The default word select is the first.
unsigned widx = 0;
if (sig->array_dimensions() > 0) {
assert(!idx_.empty());
const name_component_t&name_tail = path_.back();
NetExpr*tmp_ex = elab_and_eval(des, scope, idx_[0], -1);
if (sig->array_dimensions() > 0) {
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_head = name_tail.index.front();
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
assert(tmp);
@@ -2260,7 +2337,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
cerr << get_line() << ": debug: Use [" << widx << "]"
<< " to index l-value array." << endl;
} else {
} else if (!name_tail.index.empty()) {
if (! eval_part_select_(des, scope, sig, midx, lidx))
return 0;
}
@@ -2348,7 +2425,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
cerr << get_line() << ": error: no wire/reg " << path_
<< " in module " << scope->name() << "." << endl;
<< " in module " << scope_path(scope) << "." << endl;
des->errors += 1;
return 0;
}
@@ -2367,7 +2444,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
case NetNet::NOT_A_PORT:
cerr << get_line() << ": error: signal " << path_ << " in"
<< " module " << scope->name() << " is not a port." << endl;
<< " module " << scope_path(scope) << " is not a port." << endl;
cerr << get_line() << ": : Are you missing an input/"
<< "output/inout declaration?" << endl;
des->errors += 1;
@@ -2379,7 +2456,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
case NetNet::PIMPLICIT:
cerr << get_line() << ": internal error: signal " << path_
<< " in module " << scope->name() << " is left as "
<< " in module " << scope_path(scope) << " is left as "
<< "port type PIMPLICIT." << endl;
des->errors += 1;
return 0;
@@ -2941,6 +3018,19 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* Revision 1.207 2007/06/12 04:05:45 steve
* Put instantiated modules in the proper generated scope.
*
* Revision 1.206 2007/06/04 02:19:07 steve
* Handle bit/part select of array words in nets.
*
* Revision 1.205 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.204 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.203 2007/04/18 01:40:49 steve
* Fix elaboration of multiply of two constants.
*
+36 -19
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_pexpr.cc,v 1.25 2006/11/04 06:19:25 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.28 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -25,6 +25,7 @@
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include "netmisc.h"
# include <iostream>
@@ -130,47 +131,53 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
hname_t path = path_;
char*name = path.remove_tail_name();
pform_name_t path = path_;
name_component_t name_tail = path_.back();
path.pop_back();
NetScope*pscope = scope;
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
perm_string perm_name = lex_strings.make(name);
delete name;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, path);
pscope = des->find_scope(scope, tmp);
}
const NetExpr*ex_msb;
const NetExpr*ex_lsb;
const NetExpr*ex = pscope->get_parameter(perm_name, ex_msb, ex_lsb);
const NetExpr*ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
des->errors += 1;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, perm_name);
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
res->set_line(*this);
assert(res);
if (msb_ && lsb_) {
assert(idx_.empty());
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
switch (use_sel) {
case index_component_t::SEL_NONE:
break;
default:
case index_component_t::SEL_PART:
cerr << get_line() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
break;
} else if (!idx_.empty()) {
assert(msb_==0);
assert(lsb_==0);
assert(idx_.size() == 1);
case index_component_t::SEL_BIT:
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = idx_[0]->elaborate_pexpr(des, scope);
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
break;
}
return res;
@@ -236,6 +243,16 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.28 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.27 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.26 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.25 2006/11/04 06:19:25 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
+24 -22
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_scope.cc,v 1.44 2007/03/22 16:08:15 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.46 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -51,7 +51,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
{
if (debug_scopes) {
cerr << get_line() << ": debug: Elaborate scope "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
}
// Generate all the parameters that this instance of this
@@ -66,7 +66,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// place of the elaborated expression.
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
// This loop scans the parameters in the module, and creates
@@ -156,7 +156,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
}
}
@@ -200,7 +200,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// here because the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (hparm_it_t cur = defparms.begin()
for (pform_parm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -243,7 +243,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
NetScope*task_scope = new NetScope(scope, (*cur).first,
hname_t use_name( (*cur).first );
NetScope*task_scope = new NetScope(scope, use_name,
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -258,7 +259,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
NetScope*func_scope = new NetScope(scope, (*cur).first,
hname_t use_name( (*cur).first );
NetScope*func_scope = new NetScope(scope, use_name,
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -351,11 +353,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// that each instance has a unique name in the
// container. The format of using [] is part of the
// Verilog standard.
char name_buf[128];
snprintf(name_buf, sizeof name_buf,
"%s[%d]", scope_name.str(), genvar);
perm_string use_name = lex_strings.make(name_buf);
hname_t use_name (scope_name, genvar);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create generated scope " << use_name << endl;
@@ -431,7 +429,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// about to create, and if I find it then somebody beat me to
// it.
if (sc->child(get_name())) {
if (sc->child(hname_t(get_name()))) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
@@ -454,8 +452,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
<< scn->name() << "." << endl;
<< scope_path(sc) << "." << get_name() << " within "
<< scope_path(scn) << "." << endl;
des->errors += 1;
return;
@@ -498,24 +496,21 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// instantiation line.
for (int idx = 0 ; idx < instance_count ; idx += 1) {
perm_string use_name = get_name();
hname_t use_name (get_name());
if (instance_array) {
char name_buf[128];
int instance_idx = idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
instance_idx = instance_low - idx;
snprintf(name_buf, sizeof name_buf,
"%s[%d]", get_name().str(), instance_idx);
use_name = lex_strings.make(name_buf);
use_name = hname_t(get_name(), instance_idx);
}
if (debug_scopes) {
cerr << get_line() << ": debug: Module instance " << use_name
<< " becomes child of " << sc->name()
<< " becomes child of " << scope_path(sc)
<< "." << endl;
}
@@ -652,7 +647,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
NetScope*my_scope = scope;
if (name_ != 0) {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
my_scope = new NetScope(scope, hname_t(name_), bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -761,6 +756,13 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.46 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.45 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.44 2007/03/22 16:08:15 steve
* Spelling fixes from Larry
*
+98 -65
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.49 2007/04/02 01:12:34 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -34,6 +34,7 @@
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
# include "ivl_assert.h"
/*
* This local function checks if a named signal is connected to a
@@ -41,8 +42,10 @@
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const hname_t&name)
NetNet*sig)
{
perm_string name = sig->name();
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
@@ -53,9 +56,15 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
// This port has an internal connection. In this case,
// the port has 0 or more NetEIdent objects concatenated
// together that form the port.
// Note that module ports should not have any heirarchy
// in their names: they are in the root of the module
// scope by definition.
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
perm_string pname = peek_tail_name(pp->expr[cc]->path());
assert(pp->expr[cc]);
if (pp->expr[cc]->path() == name)
if (pname == name)
return true;
}
}
@@ -63,14 +72,28 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
return false;
}
#if 0
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
{
NetScope*cur = scope;
unsigned idx = 0;
while (path.peek_name(idx+1)) {
cur = cur->child(path.peek_name(idx));
if (cur == 0)
return 0;
idx += 1;
}
return cur->find_signal(path.peek_name(idx));
}
#endif
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const map<hname_t,PWire*>&wl = get_wires();
// Scan all the ports of the module, and make sure that each
// is connected to wires that have port declarations.
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
@@ -78,12 +101,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (pp == 0)
continue;
map<hname_t,PWire*>::const_iterator wt;
map<pform_name_t,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
hname_t port_path (pp->expr[cc]->path());
wt = wl.find(port_path);
pform_name_t port_path (pp->expr[cc]->path());
wt = wires_.find(port_path);
if (wt == wl.end()) {
if (wt == wires_.end()) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
@@ -103,14 +126,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
}
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
; wt != wires_.end() ; wt ++ ) {
PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope);
NetNet*sig = scope->find_signal_in_child(cur->path());
NetNet*sig = cur->elaborate_sig(des, scope);
// If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that
@@ -122,12 +142,10 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
hname_t name = (*wt).first;
if (! signal_is_in_port(ports, name)) {
if (! signal_is_in_port(ports, sig)) {
cerr << cur->get_line() << ": error: Signal "
<< name << " has a declared direction "
<< sig->name() << " has a declared direction "
<< "but is not a port." << endl;
des->errors += 1;
}
@@ -190,11 +208,13 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
NetScope*fscope = scope->child((*cur).first);
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
if (scope == 0) {
cerr << (*cur).second->get_line() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope->name() << "." << endl;
<< " missing in " << scope_path(scope) << "." << endl;
des->errors += 1;
continue;
}
@@ -211,7 +231,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child((*cur).first);
NetScope*tscope = scope->child( hname_t((*cur).first) );
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
@@ -234,9 +254,9 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
if (my_scope->parent() != scope) {
cerr << get_line() << ": internal error: "
<< "Instance " << my_scope->name()
<< " is in parent " << my_scope->parent()->name()
<< " instead of " << scope->name()
<< "Instance " << scope_path(my_scope)
<< " is in parent " << scope_path(my_scope->parent())
<< " instead of " << scope_path(scope)
<< endl;
}
assert(my_scope->parent() == scope);
@@ -259,7 +279,7 @@ bool PGenerate::elaborate_sig(Design*des) const
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate nets in "
<< "scope " << (*cur)->name() << endl;
<< "scope " << scope_path(*cur) << endl;
flag = elaborate_sig_(des, *cur) & flag;
}
@@ -270,7 +290,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
{
// Scan the declared PWires to elaborate the obvious signals
// in the current scope.
typedef map<hname_t,PWire*>::const_iterator wires_it_t;
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
for (wires_it_t wt = wires.begin()
; wt != wires.end() ; wt ++ ) {
@@ -278,7 +298,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate PWire "
<< cur->path() << " in scope " << scope->name() << endl;
<< cur->path() << " in scope " << scope_path(scope) << endl;
cur->elaborate_sig(des, scope);
}
@@ -404,22 +424,24 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <func>.<port>. */
hname_t path = (*ports_)[idx]->path();
perm_string pname = lex_strings.make(path.peek_name(1));
perm_string ppath = lex_strings.make(path.peek_name(0));
pform_name_t path = (*ports_)[idx]->path();
ivl_assert(*this, path.size() == 2);
perm_string pname = peek_tail_name(path);
perm_string ppath = peek_head_name(path);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->path()
<< " has wrong name for function "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
des->errors += 1;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope->name() << " is missing port "
<< scope_path(scope) << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
@@ -457,36 +479,34 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <task>.<port>. */
hname_t path = (*ports_)[idx]->path();
assert(path.peek_name(0) && path.peek_name(1));
pform_name_t path = (*ports_)[idx]->path();
ivl_assert(*this, path.size() == 2);
perm_string scope_name = peek_head_name(path);
perm_string port_name = peek_tail_name(path);
/* check that the current scope really does have the
name of the first component of the task port name. Do
this by looking up the task scope in the parent of
the current scope. */
if (scope->parent()->child(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
}
ivl_assert(*this, scope->basename() == scope_name);
/* Find the signal for the port. We know by definition
that it is in the scope of the task, so look only in
the scope. */
NetNet*tmp = scope->find_signal(path.peek_name(1));
NetNet*tmp = scope->find_signal(port_name);
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl;
<< "Could not find port " << port_name
<< " in scope " << scope_path(scope) << endl;
scope->dump(cerr);
}
ports[idx] = tmp;
}
NetTaskDef*def = new NetTaskDef(scope->name(), ports);
NetTaskDef*def = new NetTaskDef(scope, ports);
scope->set_task_def(def);
}
@@ -502,16 +522,19 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
* elaboration this creates an object in the design that represent the
* defined item.
*/
void PWire::elaborate_sig(Design*des, NetScope*scope) const
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{
/* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to
elaborate the NetNet object. */
{ hname_t tmp_path = hname_;
free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
scope = scope->child(tmp_path.peek_name(idx));
{ pform_name_t tmp_path = hname_;
tmp_path.pop_back();
while (! tmp_path.empty()) {
name_component_t cur = tmp_path.front();
tmp_path.pop_front();
scope = scope->child( hname_t(cur.name) );
if (scope == 0) {
cerr << get_line() << ": internal error: "
@@ -564,7 +587,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
des->errors += 1;
return;
return 0;
}
mnum[idx] = tmp->value().as_long();
@@ -577,7 +600,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
"Unable to evaluate constant expression ``" <<
*lsb_[idx] << "''." << endl;
des->errors += 1;
return;
return 0;
}
lnum[idx] = tmp->value().as_long();
@@ -593,7 +616,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return;
return 0;
}
@@ -606,7 +629,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << hname_ << "''" << endl;
des->errors += 1;
return;
return 0;
}
}
@@ -641,9 +664,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if ((lexp == 0) || (rexp == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< hname_.peek_tail_name() << "''." << endl;
<< hname_ << "''." << endl;
des->errors += 1;
return;
return 0;
}
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
@@ -652,9 +675,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if ((lcon == 0) || (rcon == 0)) {
cerr << get_line() << ": internal error: The indices "
<< "are not constant for array ``"
<< hname_.peek_tail_name() << "''." << endl;
<< hname_ << "''." << endl;
des->errors += 1;
return;
return 0;
}
verinum lval = lcon->value();
@@ -663,8 +686,6 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
delete lexp;
delete rexp;
perm_string name = lex_strings.make(hname_.peek_tail_name());
array_dimensions = 1;
array_s0 = lval.as_long();
array_e0 = rval.as_long();
@@ -704,11 +725,11 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
}
}
perm_string name = lex_strings.make(hname_.peek_tail_name());
perm_string name = peek_tail_name(hname_);
if (debug_elaborate) {
cerr << get_line() << ": debug: Create signal "
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
<< " in scope " << scope->name() << endl;
<< " in scope " << scope_path(scope) << endl;
}
@@ -722,7 +743,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Signal " << name
<< " in scope " << scope->name()
<< " in scope " << scope_path(scope)
<< " defaults to data type " << use_data_type << endl;
}
}
@@ -738,10 +759,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
return sig;
}
/*
* $Log: elab_sig.cc,v $
* Revision 1.52 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.51 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.50 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.49 2007/04/02 01:12:34 steve
* Seperate arrayness from word count
*
+47 -22
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.370 2007/04/16 01:10:07 steve Exp $"
#ident "$Id: elaborate.cc,v 1.374 2007/06/05 21:35:51 steve Exp $"
#endif
# include "config.h"
@@ -123,8 +123,14 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
return;
}
assert(rid);
assert(rid->pin_count() == 1);
ivl_assert(*this, rid);
if (rid->pin_count() != 1) {
cerr << get_line() << ": internal error: "
<< "Invalid elaborate_net results here:" << endl;
rid->dump_net(cerr, 4);
des->errors += 1;
}
ivl_assert(*this, rid->pin_count() == 1);
/* If the right hand net is the same type as the left
side net (i.e., WIRE/WIRE) then it is enough to just
@@ -651,7 +657,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (debug_elaborate) {
cerr << get_line() << ": debug: Instantiate module "
<< rmod->mod_name() << " with instance name "
<< get_name() << " in scope " << scope->name() << endl;
<< get_name() << " in scope " << scope_path(scope) << endl;
}
// This is the array of pin expressions, shuffled to match the
@@ -770,8 +776,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (mport.count() == 0)
continue;
NetNet*tmp = des->find_signal(instance[0],
mport[0]->path());
perm_string pname = peek_tail_name(mport[0]->path());
NetNet*tmp = instance[0]->find_signal(pname);
assert(tmp);
if (tmp->port_type() == NetNet::PINPUT) {
@@ -944,7 +951,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (debug_elaborate) {
cerr << get_line() << ": debug: " << get_name()
<< ": Port " << idx << " has vector width of "
<< ": Port " << (idx+1) << " has vector width of "
<< prts_vector_width << "." << endl;
}
@@ -953,8 +960,10 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// based, but users count parameter positions from 1.
if ((instance.count() == 1)
&& (prts_vector_width != sig->vector_width())) {
const char *tmp3 = rmod->ports[idx]->name.str();
if (tmp3 == 0) tmp3 = "???";
cerr << get_line() << ": warning: Port " << (idx+1)
<< " (" << rmod->ports[idx]->name << ") of "
<< " (" << tmp3 << ") of "
<< type_ << " expects " << prts_vector_width <<
" bits, got " << sig->vector_width() << "." << endl;
@@ -1494,7 +1503,6 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
NetESignal*sig = new NetESignal(tmp);
/* Generate an assignment of the l-value to the temporary... */
string n = scope->local_hsymbol();
NetAssign_*lvt = new NetAssign_(tmp);
NetAssign*a1 = new NetAssign(lvt, rv);
@@ -1617,10 +1625,10 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
NetScope*nscope = 0;
if (name_.str() != 0) {
nscope = scope->child(name_);
nscope = scope->child(hname_t(name_));
if (nscope == 0) {
cerr << get_line() << ": internal error: "
"unable to find block scope " << scope->name()
"unable to find block scope " << scope_path(scope)
<< "<" << name_ << ">" << endl;
des->errors += 1;
return 0;
@@ -1833,7 +1841,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const
{
if (path_.peek_name(0)[0] == '$')
if (peek_tail_name(path_)[0] == '$')
return elaborate_sys(des, scope);
else
return elaborate_usr(des, scope);
@@ -1877,7 +1885,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
}
}
NetSTask*cur = new NetSTask(path_.peek_name(0), eparms);
NetSTask*cur = new NetSTask(peek_tail_name(path_), eparms);
return cur;
}
@@ -1926,7 +1934,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
NetTaskDef*def = task->task_def();
if (def == 0) {
cerr << get_line() << ": internal error: task " << path_
<< " doesn't have a definition in " << scope->name()
<< " doesn't have a definition in " << scope_path(scope)
<< "." << endl;
des->errors += 1;
return 0;
@@ -2137,10 +2145,12 @@ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
NetScope*target = des->find_scope(scope, scope_);
list<hname_t> spath = eval_scope_path(des, scope, scope_);
NetScope*target = des->find_scope(scope, spath);
if (target == 0) {
cerr << get_line() << ": error: Cannot find scope "
<< scope_ << " in " << scope->name() << endl;
<< scope_ << " in " << scope_path(scope) << endl;
des->errors += 1;
return 0;
}
@@ -2757,7 +2767,7 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
if (def == 0) {
cerr << get_line() << ": internal error: "
<< "No function definition for function "
<< scope->name() << endl;
<< scope_path(scope) << endl;
return;
}
@@ -2766,7 +2776,7 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
NetProc*st = statement_->elaborate(des, scope);
if (st == 0) {
cerr << statement_->get_line() << ": error: Unable to elaborate "
"statement in function " << def->name() << "." << endl;
"statement in function " << scope->basename() << "." << endl;
des->errors += 1;
return;
}
@@ -2867,7 +2877,7 @@ void PTask::elaborate(Design*des, NetScope*task) const
st = statement_->elaborate(des, task);
if (st == 0) {
cerr << statement_->get_line() << ": Unable to elaborate "
"statement in task " << task->name()
"statement in task " << scope_path(task)
<< " at " << get_line() << "." << endl;
return;
}
@@ -3225,7 +3235,8 @@ bool Module::elaborate(Design*des, NetScope*scope) const
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
NetScope*fscope = scope->child((*cur).first);
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
assert(fscope);
(*cur).second->elaborate(des, fscope);
}
@@ -3237,7 +3248,8 @@ bool Module::elaborate(Design*des, NetScope*scope) const
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child((*cur).first);
hname_t use_name ( (*cur).first );
NetScope*tscope = scope->child(use_name);
assert(tscope);
(*cur).second->elaborate(des, tscope);
}
@@ -3286,7 +3298,7 @@ bool PGenerate::elaborate(Design*des) const
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate in "
<< "scope " << (*cur)->name() << endl;
<< "scope " << scope_path(*cur) << endl;
flag = elaborate_(des, *cur) & flag;
}
@@ -3416,6 +3428,19 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.374 2007/06/05 21:35:51 steve
* Error resiliency (ldoolitt)
*
* Revision 1.373 2007/06/04 02:19:07 steve
* Handle bit/part select of array words in nets.
*
* Revision 1.372 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.371 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.370 2007/04/16 01:10:07 steve
* Properly ignore unsupported ifnone.
*
+22 -14
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.cc,v 1.45 2007/03/07 00:38:15 steve Exp $"
#ident "$Id: eval.cc,v 1.47 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
@@ -29,12 +29,12 @@
# include "netmisc.h"
# include "compiler.h"
verinum* PExpr::eval_const(const Design*, NetScope*) const
verinum* PExpr::eval_const(Design*, NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(const Design*des, NetScope*scope) const
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
{
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
@@ -143,7 +143,7 @@ verinum* PEBinary::eval_const(const Design*des, NetScope*scope) const
delete r;
return res;
}
verinum* PEConcat::eval_const(const Design*des, NetScope*scope) const
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
{
verinum*accum = parms_[0]->eval_const(des, scope);
if (accum == 0)
@@ -170,23 +170,24 @@ verinum* PEConcat::eval_const(const Design*des, NetScope*scope) const
* Evaluate an identifier as a constant expression. This is only
* possible if the identifier is that of a parameter.
*/
verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
{
assert(scope);
NetNet*net;
NetEvent*eve;
const NetExpr*expr;
const name_component_t&name_tail = path_.back();
// Handle the special case that this ident is a genvar
// variable name. In that case, the genvar meaning preempts
// everything and we just return that value immediately.
if (scope->genvar_tmp
&& strcmp(path_.peek_tail_name(),scope->genvar_tmp) == 0) {
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
return new verinum(scope->genvar_tmp_val);
}
symbol_search(des, scope, path_,
net, expr, eve);
symbol_search(des, scope, path_, net, expr, eve);
if (expr == 0)
return 0;
@@ -201,30 +202,30 @@ verinum* PEIdent::eval_const(const Design*des, NetScope*scope) const
assert(eval);
if (msb_ || lsb_)
if (!name_tail.index.empty())
return 0;
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(const Design*, NetScope*) const
verinum* PEFNumber::eval_const(Design*, NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(const Design*, NetScope*) const
verinum* PENumber::eval_const(Design*, NetScope*) const
{
return new verinum(value());
}
verinum* PEString::eval_const(const Design*, NetScope*) const
verinum* PEString::eval_const(Design*, NetScope*) const
{
return new verinum(string(text_));
}
verinum* PETernary::eval_const(const Design*des, NetScope*scope) const
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
{
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
@@ -244,7 +245,7 @@ verinum* PETernary::eval_const(const Design*des, NetScope*scope) const
}
}
verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
{
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
@@ -275,6 +276,13 @@ verinum* PEUnary::eval_const(const Design*des, NetScope*scope) const
/*
* $Log: eval.cc,v $
* Revision 1.47 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.46 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.45 2007/03/07 00:38:15 steve
* Lint fixes.
*
+5 -3
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_attrib.cc,v 1.8 2005/11/27 17:01:57 steve Exp $"
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
@@ -35,8 +35,7 @@
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
const Design*des,
NetScope*scope)
Design*des, NetScope*scope)
{
natt = att.size();
if (natt == 0)
@@ -74,6 +73,9 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
/*
* $Log: eval_attrib.cc,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
+9 -3
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_tree.cc,v 1.75 2007/04/07 04:46:18 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.77 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -1056,7 +1056,7 @@ NetEConst* NetEBShift::eval_tree(int prune_to_width)
wid = lv.len() + shift;
}
if (prune_to_width > 0 && wid > prune_to_width)
if (prune_to_width > 0 && wid > (unsigned)prune_to_width)
wid = prune_to_width;
assert(wid);
@@ -1212,7 +1212,7 @@ NetExpr* NetEParam::eval_tree(int prune_to_width)
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
<< scope_->name() << endl;
<< scope_path(scope_) << endl;
return 0;
}
@@ -1655,6 +1655,12 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
/*
* $Log: eval_tree.cc,v $
* Revision 1.77 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.76 2007/05/31 18:36:06 steve
* Fix warning (ldolittle)
*
* Revision 1.75 2007/04/07 04:46:18 steve
* Handle evaluate of addition of real valued constants.
*
+4 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: expr_synth.cc,v 1.86 2007/04/15 01:37:29 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.87 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -92,7 +92,6 @@ NetNet* NetEBBits::synthesize(Design*des)
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
if (lsig->vector_width() != rsig->vector_width()) {
cerr << get_line() << ": internal error: bitwise (" << op_
@@ -871,6 +870,9 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.87 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.86 2007/04/15 01:37:29 steve
* Allow bit/part select of vectors in continuous assignments.
*
+74 -6
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.46 2004/09/10 00:15:45 steve Exp $"
#ident "$Id: lexor.lex,v 1.48 2007/05/30 23:21:20 steve Exp $"
#endif
# include "config.h"
@@ -70,7 +70,14 @@ struct include_stack_t {
static void emit_pathline(struct include_stack_t *isp);
/*
* The file_queue is a singly-linked list of the files that were
* listed on the command line/file list.
*/
static struct include_stack_t*file_queue = 0;
/*
* The istack is the inclusion stack.
*/
static struct include_stack_t*istack = 0;
static struct include_stack_t*standby = 0;
@@ -111,11 +118,11 @@ static void ifdef_leave(void)
if (strcmp(istack->path,cur->path) != 0) {
fprintf(stderr, "%s:%u: warning: "
"This `endif matches an ifdef in another file.\n",
istack->path, istack->lineno);
istack->path, istack->lineno+1);
fprintf(stderr, "%s:%u: : "
"This is the odd matched `ifdef.\n",
cur->path, cur->lineno);
cur->path, cur->lineno+1);
}
free(cur->path);
@@ -309,7 +316,24 @@ W [ \t\b\f]+
yy_push_state(IFDEF_SUPR);
}
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
<IFDEF_TRUE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
BEGIN(IFDEF_SUPR);
}
<IFDEF_FALSE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
char*name = strchr(yytext, '`');
assert(name);
name += 6;
name += strspn(name, " \t\b\f");
if (is_defined(name)) {
BEGIN(IFDEF_TRUE);
} else {
BEGIN(IFDEF_FALSE);
}
}
<IFDEF_SUPR>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { }
<IFDEF_TRUE>`else { BEGIN(IFDEF_SUPR); }
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>`else { }
@@ -322,6 +346,42 @@ W [ \t\b\f]+
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
`ifdef {
fprintf(stderr, "%s:%u: `ifdef without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`ifndef {
fprintf(stderr, "%s:%u: `ifndef without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`elsif {
fprintf(stderr, "%s:%u: `elsif without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
fprintf(stderr, "%s:%u: `elsif without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`else {
fprintf(stderr, "%s:%u: `else without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`endif {
fprintf(stderr, "%s:%u: `endif without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
/* This pattern notices macros and arranges for them to be replaced. */
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
@@ -759,7 +819,7 @@ static void lexor_done()
ifdef_stack = cur->next;
fprintf(stderr, "%s:%u: error: This `ifdef lacks an `endif.\n",
cur->path, cur->lineno);
cur->path, cur->lineno+1);
free(cur->path);
free(cur);
@@ -777,11 +837,14 @@ static int yywrap()
int line_mask_flag = 0;
struct include_stack_t*isp = istack;
istack = isp->next;
FILE *delayed_close = (FILE *) 0;
/* Delete the current input buffers, and free the cell. */
yy_delete_buffer(YY_CURRENT_BUFFER);
if (isp->file) {
fclose(isp->file);
/* Delay the close of this file, because the yyrestart
below seems to have some memory of this file. */
delayed_close = isp->file;
free(isp->path);
} else {
/* If I am printing line directives and I just finished
@@ -825,6 +888,7 @@ static int yywrap()
}
yyrestart(istack->file);
if (delayed_close) fclose(delayed_close);
return 0;
}
@@ -833,6 +897,7 @@ static int yywrap()
top. If I need to print a line directive, do so. */
yy_switch_to_buffer(istack->yybs);
if (delayed_close) fclose(delayed_close);
if (line_direct_flag && istack->path && !line_mask_flag)
fprintf(yyout, "\n`line %u \"%s\" 2\n",
@@ -854,6 +919,7 @@ void reset_lexor(FILE*out, char*paths[])
isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r");
isp->str = 0;
isp->lineno = 0;
if (isp->file == 0) {
perror(paths[0]);
exit(1);
@@ -876,8 +942,10 @@ void reset_lexor(FILE*out, char*paths[])
for (idx = 1 ; paths[idx] ; idx += 1) {
isp = malloc(sizeof(struct include_stack_t));
isp->path = strdup(paths[idx]);
isp->file = 0;
isp->str = 0;
isp->next = 0;
isp->lineno = 0;
if (tail)
tail->next = isp;
else
+18 -2
View File
@@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.95 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: lexor.lex,v 1.96 2007/06/14 03:50:00 steve Exp $"
#endif
# include "config.h"
@@ -109,6 +109,7 @@ static int comment_enter;
%s UDPTABLE
%x PPTIMESCALE
%x PPDEFAULT_NETTYPE
%s EDGES
W [ \t\b\f\r]+
@@ -167,7 +168,7 @@ W [ \t\b\f\r]+
with "*" and return that. */
"("{W}*"*"{W}*")" { return '*'; }
<EDGES>"]" { BEGIN(0); return yytext[0]; }
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); }
@@ -210,6 +211,17 @@ W [ \t\b\f\r]+
<UDPTABLE>[pP] { return 'p'; }
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
<EDGES>"01" { return K_edge_descriptor; }
<EDGES>"0x" { return K_edge_descriptor; }
<EDGES>"0z" { return K_edge_descriptor; }
<EDGES>"10" { return K_edge_descriptor; }
<EDGES>"1x" { return K_edge_descriptor; }
<EDGES>"1z" { return K_edge_descriptor; }
<EDGES>"x0" { return K_edge_descriptor; }
<EDGES>"x1" { return K_edge_descriptor; }
<EDGES>"z0" { return K_edge_descriptor; }
<EDGES>"z1" { return K_edge_descriptor; }
[a-zA-Z_][a-zA-Z0-9$_]* {
int rc = lexor_keyword_code(yytext, yyleng);
switch (rc) {
@@ -230,6 +242,10 @@ W [ \t\b\f\r]+
}
break;
case K_edge:
BEGIN(EDGES);
break;
default:
yylval.text = 0;
break;
+6 -3
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: veriusertfs.c,v 1.16 2006/10/30 22:45:37 steve Exp $"
#ident "$Id: veriusertfs.c,v 1.17 2007/05/08 22:01:26 steve Exp $"
#endif
/*
@@ -58,7 +58,7 @@ void veriusertfs_register_table(p_tfcell vtable)
p_tfcell tf;
s_vpi_systf_data tf_data;
p_pli_data data;
char trace_buf[1024];
static char trace_buf[1024];
if (!pli_trace && (path = getenv("PLI_TRACE"))) {
if (strcmp(path,"-") == 0)
@@ -69,8 +69,8 @@ void veriusertfs_register_table(p_tfcell vtable)
perror(path);
exit(1);
}
setvbuf(pli_trace, trace_buf, _IOLBF, sizeof(trace_buf));
}
setvbuf(pli_trace, trace_buf, _IOLBF, sizeof(trace_buf));
}
for (tf = vtable; tf; tf++) {
@@ -389,6 +389,9 @@ PLI_INT32 tf_setrealdelay(double dly)
}
/*
* $Log: veriusertfs.c,v $
* Revision 1.17 2007/05/08 22:01:26 steve
* Trace file line buffer must be static.
*
* Revision 1.16 2006/10/30 22:45:37 steve
* Updates for Cygwin portability (pr1585922)
*
+70 -64
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_design.cc,v 1.50 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: net_design.cc,v 1.54 2007/06/05 04:18:09 steve Exp $"
#endif
# include "config.h"
@@ -32,6 +32,7 @@
# include "netlist.h"
# include "util.h"
# include "compiler.h"
# include "netmisc.h"
# include <sstream>
Design:: Design()
@@ -84,7 +85,7 @@ uint64_t Design::scale_to_precision(uint64_t val,
NetScope* Design::make_root_scope(perm_string root)
{
NetScope *root_scope_;
root_scope_ = new NetScope(0, root, NetScope::MODULE);
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE);
/* This relies on the fact that the basename return value is
permallocated. */
root_scope_->set_module_name(root_scope_->basename());
@@ -114,26 +115,27 @@ const list<NetScope*> Design::find_root_scopes() const
* more step down the tree until the name runs out or the search
* fails.
*/
NetScope* Design::find_scope(const hname_t&path) const
NetScope* Design::find_scope(const std::list<hname_t>&path) const
{
if (path.peek_name(0) == 0)
if (path.empty())
return 0;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); scope++) {
NetScope*cur = *scope;
if (strcmp(path.peek_name(0), cur->basename()) != 0)
if (path.front() != cur->fullname())
continue;
unsigned hidx = 1;
while (cur) {
const char*name = path.peek_name(hidx);
if (name == 0)
return cur;
std::list<hname_t> tmp = path;
tmp.pop_front();
cur = cur->child(name);
hidx += 1;
while (cur) {
if (tmp.empty()) return cur;
cur = cur->child( tmp.front() );
tmp.pop_front();
}
}
@@ -143,28 +145,34 @@ NetScope* Design::find_scope(const hname_t&path) const
/*
* This is a relative lookup of a scope by name. The starting point is
* the scope parameter is the place within which I start looking for
* the scope. If I do not find the scope within the passed scope,
* start looking in parent scopes until I find it, or I run out of
* parent scopes.
* the scope parameter within which I start looking for the scope. If
* I do not find the scope within the passed scope, start looking in
* parent scopes until I find it, or I run out of parent scopes.
*/
NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
NetScope* Design::find_scope(NetScope*scope, const std::list<hname_t>&path) const
{
assert(scope);
if (path.peek_name(0) == 0)
if (path.empty())
return scope;
for ( ; scope ; scope = scope->parent()) {
unsigned hidx = 0;
const char*key = path.peek_name(hidx);
std::list<hname_t> tmp = path;
NetScope*cur = scope;
do {
cur = cur->child(key);
if (cur == 0) break;
hidx += 1;
key = path.peek_name(hidx);
} while (key);
hname_t key = tmp.front();
if (cur->type() == NetScope::MODULE
&& cur->module_name()==key.peek_name()) {
/* Up references may match module name */
} else {
cur = cur->child( key );
if (cur == 0) break;
}
tmp.pop_front();
} while (!tmp.empty());
if (cur) return cur;
}
@@ -196,18 +204,19 @@ void NetScope::run_defparams(Design*des)
}
}
map<hname_t,NetExpr*>::const_iterator pp;
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
NetExpr*val = (*pp).second;
hname_t path = (*pp).first;
pform_name_t path = (*pp).first;
char*tmp = path.remove_tail_name();
perm_string perm_name = lex_strings.make(tmp);
delete[]tmp;
perm_string perm_name = peek_tail_name(path);
path.pop_back();
list<hname_t> eval_path = eval_scope_path(des, this, path);
/* If there is no path on the name, then the targ_scope
is the current scope. */
NetScope*targ_scope = des->find_scope(this, path);
NetScope*targ_scope = des->find_scope(this, eval_path);
if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " <<
path << "." << perm_name << " not found." << endl;
@@ -218,7 +227,7 @@ void NetScope::run_defparams(Design*des)
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< perm_name << " not found in "
<< targ_scope->name() << "." << endl;
<< scope_path(targ_scope) << "." << endl;
}
}
@@ -425,68 +434,52 @@ const char* Design::get_flag(const string&key) const
* It is the job of this function to properly implement Verilog scope
* rules as signals are concerned.
*/
NetNet* Design::find_signal(NetScope*scope, hname_t path)
NetNet* Design::find_signal(NetScope*scope, pform_name_t path)
{
assert(scope);
char*key = path.remove_tail_name();
if (path.peek_name(0))
scope = find_scope(scope, path);
perm_string key = peek_tail_name(path);
path.pop_back();
if (! path.empty()) {
list<hname_t> eval_path = eval_scope_path(this, scope, path);
scope = find_scope(scope, eval_path);
}
while (scope) {
if (NetNet*net = scope->find_signal(key)) {
delete key;
if (NetNet*net = scope->find_signal(key))
return net;
}
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
delete key;
return 0;
}
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
{
assert(scope);
NetScope*func = find_scope(scope, name);
std::list<hname_t> eval_path = eval_scope_path(this, scope, name);
NetScope*func = find_scope(scope, eval_path);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetFuncDef* Design::find_function(const hname_t&key)
NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
{
NetScope*func = find_scope(key);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetScope* Design::find_task(NetScope*scope, const hname_t&name)
{
NetScope*task = find_scope(scope, name);
std::list<hname_t> eval_path = eval_scope_path(this, scope, name);
NetScope*task = find_scope(scope, eval_path);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
NetScope* Design::find_task(const hname_t&key)
{
NetScope*task = find_scope(key);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
void Design::add_node(NetNode*net)
{
assert(net->design_ == 0);
@@ -562,6 +555,19 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.54 2007/06/05 04:18:09 steve
* Upward names may reference modules by module_name.
*
* Revision 1.53 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.52 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.51 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.50 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
+6 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_event.cc,v 1.26 2004/10/04 01:10:54 steve Exp $"
#ident "$Id: net_event.cc,v 1.27 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -56,10 +56,10 @@ perm_string NetEvent::name() const
return name_;
}
string NetEvent::full_name() const
NetScope* NetEvent::scope()
{
assert(scope_);
return scope_->name() + "." + string(name_);
return scope_;
}
const NetScope* NetEvent::scope() const
@@ -449,6 +449,9 @@ NetProc* NetEvWait::statement()
/*
* $Log: net_event.cc,v $
* Revision 1.27 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.26 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
+6 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_func.cc,v 1.9 2007/04/17 04:17:47 steve Exp $"
#ident "$Id: net_func.cc,v 1.10 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -95,13 +95,13 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
if (dscope->type() != NetScope::FUNC) {
cerr << get_line() << ": error: Attempt to call scope "
<< dscope->name() << " as a function." << endl;
<< scope_path(dscope) << " as a function." << endl;
des->errors += 1;
return false;
}
if (parms_count != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
cerr << get_line() << ": error: Function " << scope_path(dscope)
<< " expects " << (dscope->func_def()->port_count())
<< " arguments, you passed " << parms_count << "."
<< endl;
@@ -149,6 +149,9 @@ unsigned NetSysFunc::vector_width() const
/*
* $Log: net_func.cc,v $
* Revision 1.10 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.9 2007/04/17 04:17:47 steve
* Fix argument count in function error message.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_link.cc,v 1.20 2007/03/26 18:17:50 steve Exp $"
#ident "$Id: net_link.cc,v 1.21 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -391,7 +391,7 @@ const char* Nexus::name() const
}
assert(sig);
ostringstream tmp;
tmp << sig->scope()->name() << "." << sig->name();
tmp << scope_path(sig->scope()) << "." << sig->name();
if (sig->pin_count() > 1)
tmp << "<" << pin << ">";
@@ -525,6 +525,9 @@ bool NexusSet::intersect(const NexusSet&that) const
/*
* $Log: net_link.cc,v $
* Revision 1.21 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.20 2007/03/26 18:17:50 steve
* Remove pretense of general use for t_cookie.
*
+15 -38
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_scope.cc,v 1.36 2007/01/16 05:44:15 steve Exp $"
#ident "$Id: net_scope.cc,v 1.38 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -35,7 +35,7 @@
* in question.
*/
NetScope::NetScope(NetScope*up, perm_string n, NetScope::TYPE t)
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
: type_(t), up_(up), sib_(0), sub_(0)
{
signals_ = 0;
@@ -241,15 +241,7 @@ NetNet::Type NetScope::default_nettype() const
perm_string NetScope::basename() const
{
return name_;
}
string NetScope::name() const
{
if (up_)
return up_->name() + "." + string(name_);
else
return string(name_);
return name_.peek_name();
}
void NetScope::add_event(NetEvent*ev)
@@ -336,37 +328,16 @@ NetNet* NetScope::find_signal(const char*key)
return 0;
}
/*
* This method searches for the signal within this scope. If the path
* has hierarchy, I follow the child scopes until I get the base name,
* and look for the key in the deepest scope.
*/
NetNet* NetScope::find_signal_in_child(const hname_t&path)
{
NetScope*cur = this;
unsigned idx = 0;
while (path.peek_name(idx+1)) {
cur = cur->child(path.peek_name(idx));
if (cur == 0)
return 0;
idx += 1;
}
return cur->find_signal(path.peek_name(idx));
}
/*
* This method locates a child scope by name. The name is the simple
* name of the child, no hierarchy is searched.
*/
NetScope* NetScope::child(const char*name)
NetScope* NetScope::child(const hname_t&name)
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (strcmp(cur->name_, name) != 0) {
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
@@ -374,12 +345,12 @@ NetScope* NetScope::child(const char*name)
return cur;
}
const NetScope* NetScope::child(const char*name) const
const NetScope* NetScope::child(const hname_t&name) const
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (strcmp(cur->name_, name) != 0) {
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
@@ -403,15 +374,21 @@ perm_string NetScope::local_symbol()
res << "_s" << (lcounter_++);
return lex_strings.make(res.str());
}
#if 0
string NetScope::local_hsymbol()
{
return string(name()) + "." + string(local_symbol());
}
#endif
/*
* $Log: net_scope.cc,v $
* Revision 1.38 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.37 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.36 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
+22 -9
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.257 2007/04/02 01:12:34 steve Exp $"
#ident "$Id: netlist.cc,v 1.258 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -1770,11 +1770,16 @@ NetFuncDef::NetFuncDef(NetScope*s, NetNet*result, const svector<NetNet*>&po)
NetFuncDef::~NetFuncDef()
{
}
#if 0
const string NetFuncDef::name() const
{
return scope_->name();
}
#endif
const NetScope* NetFuncDef::scope() const
{
return scope_;
}
void NetFuncDef::set_proc(NetProc*st)
{
@@ -1850,12 +1855,12 @@ NetEUFunc::~NetEUFunc()
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
delete parms_[idx];
}
#if 0
const string NetEUFunc::name() const
{
return func_->name();
}
#endif
const NetESignal*NetEUFunc::result_sig() const
{
return result_sig_;
@@ -1893,12 +1898,12 @@ NetUTask::NetUTask(NetScope*def)
NetUTask::~NetUTask()
{
}
#if 0
const string NetUTask::name() const
{
return task_->name();
}
#endif
const NetScope* NetUTask::task() const
{
return task_;
@@ -2286,8 +2291,8 @@ unsigned NetUReduce::width() const
return width_;
}
NetTaskDef::NetTaskDef(const string&n, const svector<NetNet*>&po)
: name_(n), proc_(0), ports_(po)
NetTaskDef::NetTaskDef(NetScope*n, const svector<NetNet*>&po)
: scope_(n), proc_(0), ports_(po)
{
}
@@ -2312,11 +2317,16 @@ NetNet* NetTaskDef::port(unsigned idx)
assert(idx < ports_.count());
return ports_[idx];
}
#if 0
const string& NetTaskDef::name() const
{
return name_;
}
#endif
const NetScope* NetTaskDef::scope() const
{
return scope_;
}
const NetProc*NetTaskDef::proc() const
{
@@ -2325,6 +2335,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.258 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.257 2007/04/02 01:12:34 steve
* Seperate arrayness from word count
*
+43 -28
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.377 2007/04/17 04:34:23 steve Exp $"
#ident "$Id: netlist.h,v 1.380 2007/06/02 03:42:13 steve Exp $"
#endif
/*
@@ -33,6 +33,7 @@
# include <list>
# include <vector>
# include "ivl_target.h"
# include "pform_types.h"
# include "config.h"
# include "verinum.h"
# include "verireal.h"
@@ -2059,7 +2060,6 @@ class NetEvent : public LineInfo {
~NetEvent();
perm_string name() const;
string full_name() const;
// Get information about probes connected to me.
unsigned nprobe() const;
@@ -2266,8 +2266,9 @@ class NetFuncDef {
void set_proc(NetProc*st);
const string name() const;
//const string name() const;
const NetProc*proc() const;
const NetScope*scope() const;
NetScope*scope();
unsigned port_count() const;
@@ -2405,12 +2406,13 @@ class NetSTask : public NetProc {
class NetTaskDef {
public:
NetTaskDef(const string&n, const svector<NetNet*>&po);
NetTaskDef(NetScope*n, const svector<NetNet*>&po);
~NetTaskDef();
void set_proc(NetProc*p);
const string& name() const;
//const string& name() const;
const NetScope* scope() const;
const NetProc*proc() const;
unsigned port_count() const;
@@ -2419,7 +2421,7 @@ class NetTaskDef {
void dump(ostream&, unsigned) const;
private:
string name_;
NetScope*scope_;
NetProc*proc_;
svector<NetNet*>ports_;
@@ -2436,11 +2438,9 @@ class NetTaskDef {
class NetEUFunc : public NetExpr {
public:
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
~NetEUFunc();
const string name() const;
const NetESignal*result_sig() const;
unsigned parm_count() const;
@@ -3182,7 +3182,7 @@ class NetScope : public Attrib {
/* Create a new scope, and attach it to the given parent. The
name is expected to have been permallocated. */
NetScope(NetScope*up, perm_string name, TYPE t);
NetScope(NetScope*up, const hname_t&name, TYPE t);
~NetScope();
/* Parameters exist within a scope, and these methods allow
@@ -3220,17 +3220,14 @@ class NetScope : public Attrib {
void add_signal(NetNet*);
void rem_signal(NetNet*);
NetNet* find_signal(const char*name);
NetNet* find_signal_in_child(const hname_t&name);
/* The parent and child() methods allow users of NetScope
objects to locate nearby scopes. */
NetScope* parent();
NetScope* child(const char*name);
NetScope* child(const hname_t&name);
const NetScope* parent() const;
const NetScope* child(const char*name) const;
const NetScope* child(const hname_t&name) const;
TYPE type() const;
@@ -3269,7 +3266,7 @@ class NetScope : public Attrib {
name, whereas the basename is just my name within my parent
scope. */
perm_string basename() const;
string name() const;
const hname_t& fullname() const { return name_; }
void run_defparams(class Design*);
void evaluate_parameters(class Design*);
@@ -3277,9 +3274,6 @@ class NetScope : public Attrib {
/* This method generates a non-hierarchical name that is
guaranteed to be unique within this scope. */
perm_string local_symbol();
/* This method generates a hierarchical name that is
guaranteed to be unique globally. */
string local_hsymbol();
void dump(ostream&) const;
void emit_scope(struct target_t*tgt) const;
@@ -3294,7 +3288,7 @@ class NetScope : public Attrib {
assignments from the scope pass to the parameter evaluation
step. After that, it is not used. */
map<hname_t,NetExpr*>defparams;
map<pform_name_t,NetExpr*>defparams;
public:
/* After everything is all set up, the code generators like
@@ -3330,7 +3324,7 @@ class NetScope : public Attrib {
private:
TYPE type_;
perm_string name_;
hname_t name_;
signed char time_unit_, time_prec_;
NetNet::Type default_nettype_;
@@ -3394,8 +3388,8 @@ class Design {
path is taken as an absolute scope name. Otherwise, the
scope is located starting at the passed scope and working
up if needed. */
NetScope* find_scope(const hname_t&path) const;
NetScope* find_scope(NetScope*, const hname_t&path) const;
NetScope* find_scope(const std::list<hname_t>&path) const;
NetScope* find_scope(NetScope*, const std::list<hname_t>&path) const;
// PARAMETERS
@@ -3407,15 +3401,13 @@ class Design {
this method, unlike the NetScope::find_signal method,
handles global name binding. */
NetNet*find_signal(NetScope*scope, hname_t path);
NetNet*find_signal(NetScope*scope, pform_name_t path);
// Functions
NetFuncDef* find_function(NetScope*scope, const hname_t&key);
NetFuncDef* find_function(const hname_t&path);
NetFuncDef* find_function(NetScope*scope, const pform_name_t&key);
// Tasks
NetScope* find_task(NetScope*scope, const hname_t&name);
NetScope* find_task(const hname_t&key);
NetScope* find_task(NetScope*scope, const pform_name_t&name);
// NODES
void add_node(NetNode*);
@@ -3501,8 +3493,31 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
extern ostream& operator << (ostream&, NetNet::Type);
/*
* Manipulator to dump a scope complete path to the output. The
* manipulator is "scope_path" and works like this:
*
* out << .... << scope_path(sc) << ... ;
*/
struct __ScopePathManip { const NetScope*scope; };
inline __ScopePathManip scope_path(const NetScope*scope)
{ __ScopePathManip tmp; tmp.scope = scope; return tmp; }
extern ostream& operator << (ostream&o, __ScopePathManip);
/*
* $Log: netlist.h,v $
* Revision 1.380 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.379 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.378 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.377 2007/04/17 04:34:23 steve
* Fix handling calls to tasks in combinational always block
*
+38 -32
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netmisc.cc,v 1.13 2007/03/08 05:30:03 steve Exp $"
#ident "$Id: netmisc.cc,v 1.14 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -25,6 +25,8 @@
# include "netlist.h"
# include "netmisc.h"
# include "PExpr.h"
# include "pform_types.h"
# include "ivl_assert.h"
NetNet* add_to_net(Design*des, NetNet*sig, long val)
{
@@ -138,9 +140,44 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope,
return tmp;
}
std::list<hname_t> eval_scope_path(Design*des, NetScope*scope,
const pform_name_t&path)
{
list<hname_t> res;
typedef pform_name_t::const_iterator pform_path_it;
for (pform_path_it cur = path.begin() ; cur != path.end(); cur++) {
const name_component_t&comp = *cur;
if (comp.index.empty()) {
res.push_back(hname_t(comp.name));
continue;
}
assert(comp.index.size() == 1);
const index_component_t&index = comp.index.front();
assert(index.sel == index_component_t::SEL_BIT);
NetExpr*tmp = elab_and_eval(des, scope, index.msb, -1);
ivl_assert(*index.msb, tmp);
if (NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp)) {
res.push_back(hname_t(comp.name, ctmp->value().as_long()));
delete ctmp;
continue;
}
return res;
}
return res;
}
/*
* $Log: netmisc.cc,v $
* Revision 1.14 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.13 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
@@ -156,36 +193,5 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope,
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.9 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
* down this path.
*
* Revision 1.8 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.7 2004/02/18 17:11:57 steve
* Use perm_strings for named langiage items.
*
* Revision 1.6 2003/03/06 00:28:42 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.5 2003/02/26 01:29:24 steve
* LPM objects store only their base names.
*
* Revision 1.4 2002/08/31 03:48:50 steve
* Fix reverse bit ordered bit select in continuous assignment.
*
* Revision 1.3 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2001/02/11 02:15:52 steve
* Add the netmisc.cc source file.
*
*/
+16 -6
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netmisc.h,v 1.29 2007/03/08 05:30:03 steve Exp $"
#ident "$Id: netmisc.h,v 1.31 2007/06/02 03:42:13 steve Exp $"
#endif
# include "netlist.h"
@@ -39,21 +39,21 @@
* ex2 is the lsb expression for the range. If there is no range, then
* these values are set to 0.
*/
extern NetScope* symbol_search(const Design*des,
NetScope*start, hname_t path,
extern NetScope* symbol_search(Design*des,
NetScope*start, pform_name_t path,
NetNet*&net, /* net/reg */
const NetExpr*&par,/* parameter */
NetEvent*&eve, /* named event */
const NetExpr*&ex1, const NetExpr*&ex2);
inline NetScope* symbol_search(const Design*des,
NetScope*start, const hname_t&path,
inline NetScope* symbol_search(Design*des,
NetScope*start, const pform_name_t&path,
NetNet*&net, /* net/reg */
const NetExpr*&par,/* parameter */
NetEvent*&eve /* named event */)
{
const NetExpr*ex1, *ex2;
return symbol_search(des, start, path, net, /*mem,*/ par, eve, ex1, ex2);
return symbol_search(des, start, path, net, par, eve, ex1, ex2);
}
/*
@@ -123,8 +123,18 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid,
int prune_width =-1);
extern std::list<hname_t> eval_scope_path(Design*des, NetScope*scope,
const pform_name_t&path);
/*
* $Log: netmisc.h,v $
* Revision 1.31 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.30 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
+246 -235
View File
@@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 1998-2006 Stephen Williams ([email protected])
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -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.235 2007/04/21 04:45:36 steve Exp $"
#ident "$Id: parse.y,v 1.239 2007/06/14 03:50:00 steve Exp $"
#endif
# include "config.h"
@@ -98,6 +98,7 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
strdup. They can be put into lists with the texts type. */
char*text;
list<perm_string>*perm_strings;
pform_name_t*pform_name;
hname_t*hier;
@@ -123,8 +124,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
svector<PEEvent*>*event_expr;
PEIdent*indexed_identifier;
NetNet::Type nettype;
PGBuiltin::Type gatetype;
NetNet::PortType porttype;
@@ -158,7 +157,8 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
%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_endgenerate K_endmodule
%token K_edge K_edge_descriptor
%token K_else K_end K_endcase K_endfunction K_endgenerate 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_generate K_genvar
%token K_highz0 K_highz1 K_if K_ifnone
@@ -191,7 +191,6 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%type <statement> udp_initial udp_init_opt
%type <expr> udp_initial_expr_opt
%type <hier> identifier
%type <text> register_variable net_variable
%type <perm_strings> register_variable_list net_variable_list list_of_identifiers
@@ -217,13 +216,13 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%type <gate> gate_instance
%type <gates> gate_instance_list
%type <pform_name> heirarchy_identifier
%type <expr> expression expr_primary
%type <expr> lpvalue
%type <expr> delay_value delay_value_simple
%type <exprs> delay1 delay3 delay3_opt delay_value_list
%type <exprs> expression_list_with_nuls expression_list_proper
%type <exprs> cont_assign cont_assign_list
%type <indexed_identifier> indexed_identifier
%type <exprs> range range_opt
%type <nettype> net_type var_type net_type_opt
@@ -492,7 +491,7 @@ charge_strength_opt
;
defparam_assign
: identifier '=' expression
: heirarchy_identifier '=' expression
{ PExpr*tmp = $3;
if (!pform_expression_is_constant(tmp)) {
yyerror(@3, "error: parameter value "
@@ -605,7 +604,7 @@ delay_value_simple
}
}
| IDENTIFIER
{ PEIdent*tmp = new PEIdent(hname_t($1));
{ PEIdent*tmp = new PEIdent(lex_strings.make($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
@@ -671,16 +670,14 @@ dr_strength1
;
event_control
: '@' identifier
: '@' heirarchy_identifier
{ PEIdent*tmpi = new PEIdent(*$2);
tmpi->set_file(@2.text);
tmpi->set_lineno(@2.first_line);
delete $2;
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
PEventStatement*tmps = new PEventStatement(tmpe);
tmps->set_file(@1.text);
tmps->set_lineno(@1.first_line);
$$ = tmps;
delete $2;
}
| '@' '(' event_expression_list ')'
{ PEventStatement*tmp = new PEventStatement(*$3);
@@ -1033,53 +1030,30 @@ expr_primary
$$ = tmp;
}
| SYSTEM_IDENTIFIER
{ PECallFunction*tmp = new PECallFunction(hname_t($1));
{ perm_string tn = lex_strings.make($1);
PECallFunction*tmp = new PECallFunction(tn);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
/* The indexed_identifier rule matches simple identifiers as well as
indexed arrays. Part selects are handled below. */
/* The heirarchy_identifier rule matches simple identifiers as well as
indexed arrays and part selects */
| indexed_identifier
{ PEIdent*tmp = $1;
$$ = tmp;
}
/* There are 3 kinds of part selects. The basic part select has the
usual [M:L] syntax. The indexed part selects use +: or -: in
place of the : in the basic part select, and the first expression
is not limited to constant values. */
| indexed_identifier '[' expression ':' expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_PART;
$$ = tmp;
}
| indexed_identifier '[' expression K_PO_POS expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_IDX_UP;
$$ = tmp;
}
| indexed_identifier '[' expression K_PO_NEG expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_IDX_DO;
$$ = tmp;
}
| heirarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
/* An identifer followed by an expression list in parentheses is a
function call. If a system identifier, then a system function
call. */
| identifier '(' expression_list_proper ')'
| heirarchy_identifier '(' expression_list_proper ')'
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
@@ -1087,7 +1061,8 @@ expr_primary
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' expression_list_proper ')'
{ PECallFunction*tmp = new PECallFunction(hname_t($1), *$3);
{ perm_string tn = lex_strings.make($1);
PECallFunction*tmp = new PECallFunction(tn, *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
@@ -1343,39 +1318,61 @@ gatetype
/* A general identifier is a hierarchical name, with the right most
name the base of the identifier. This rule builds up a
hierarchical name from left to right, forming a list of names. */
identifier
: IDENTIFIER
{ $$ = new hname_t($1);
delete $1;
}
| identifier '.' IDENTIFIER
{ hname_t * tmp = $1;
tmp->append($3);
delete $3;
$$ = tmp;
}
;
hierarchical name from the left to the right, forming a list of
names. */
/* An indexed_identifier is an identifier with a bit-select
expression. This bit select may be an array index or bit index,
to be sorted out later. */
indexed_identifier
: identifier
{ PEIdent*tmp = new PEIdent(*$1);
tmp->sel_ = PEIdent::SEL_NONE;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| indexed_identifier '[' expression ']'
{ PEIdent*tmp = $1;
tmp->sel_ = PEIdent::SEL_NONE;
tmp->idx_.push_back($3);
$$ = tmp;
}
;
heirarchy_identifier
: IDENTIFIER
{ $$ = new pform_name_t;
$$->push_back(name_component_t(lex_strings.make($1)));
delete $1;
}
| heirarchy_identifier '.' IDENTIFIER
{ pform_name_t * tmp = $1;
tmp->push_back(name_component_t(lex_strings.make($3)));
delete $3;
$$ = tmp;
}
| heirarchy_identifier '[' expression ']'
{ pform_name_t * tmp = $1;
name_component_t&tail = tmp->back();
index_component_t itmp;
itmp.sel = index_component_t::SEL_BIT;
itmp.msb = $3;
tail.index.push_back(itmp);
$$ = tmp;
}
| heirarchy_identifier '[' expression ':' expression ']'
{ pform_name_t * tmp = $1;
name_component_t&tail = tmp->back();
index_component_t itmp;
itmp.sel = index_component_t::SEL_PART;
itmp.msb = $3;
itmp.lsb = $5;
tail.index.push_back(itmp);
$$ = tmp;
}
| heirarchy_identifier '[' expression K_PO_POS expression ']'
{ pform_name_t * tmp = $1;
name_component_t&tail = tmp->back();
index_component_t itmp;
itmp.sel = index_component_t::SEL_IDX_UP;
itmp.msb = $3;
itmp.lsb = $5;
tail.index.push_back(itmp);
$$ = tmp;
}
| heirarchy_identifier '[' expression K_PO_NEG expression ']'
{ pform_name_t * tmp = $1;
name_component_t&tail = tmp->back();
index_component_t itmp;
itmp.sel = index_component_t::SEL_IDX_DO;
itmp.msb = $3;
itmp.lsb = $5;
tail.index.push_back(itmp);
$$ = tmp;
}
;
/* This is a list of identifiers. The result is a list of strings,
each one of the identifiers in the list. These are simple,
@@ -1550,39 +1547,21 @@ signed_opt : K_signed { $$ = true; } | {$$ = false; } ;
assignments. It is more limited then the general expr_primary
rule to reflect the rules for assignment l-values. */
lpvalue
: indexed_identifier
{ PEIdent*tmp = $1;
$$ = tmp;
}
| indexed_identifier '[' expression ':' expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_PART;
$$ = tmp;
}
| indexed_identifier '[' expression K_PO_POS expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_IDX_UP;
$$ = tmp;
}
| indexed_identifier '[' expression K_PO_NEG expression ']'
{ PEIdent*tmp = $1;
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->sel_ = PEIdent::SEL_IDX_DO;
$$ = tmp;
}
| '{' expression_list_proper '}'
{ PEConcat*tmp = new PEConcat(*$2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $2;
$$ = tmp;
}
;
: heirarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
| '{' expression_list_proper '}'
{ PEConcat*tmp = new PEConcat(*$2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $2;
$$ = tmp;
}
;
/* Continuous assignments have a list of individual assignments. */
@@ -2304,67 +2283,87 @@ port_opt
port_reference
: IDENTIFIER
{ Module::port_t*ptmp;
ptmp = pform_module_port_reference($1, @1.text,
@1.first_line);
delete $1;
$$ = ptmp;
}
: IDENTIFIER
{ Module::port_t*ptmp;
ptmp = pform_module_port_reference($1, @1.text, @1.first_line);
delete $1;
$$ = ptmp;
}
| IDENTIFIER '[' expression ':' expression ']'
{ PEIdent*wtmp = new PEIdent(hname_t($1));
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) {
yyerror(@3, "error: msb expression of "
"port part select must be constant.");
}
if (!pform_expression_is_constant($5)) {
yyerror(@5, "error: lsb expression of "
"port part select must be constant.");
}
wtmp->msb_ = $3;
wtmp->lsb_ = $5;
wtmp->sel_ = PEIdent::SEL_PART;
Module::port_t*ptmp = new Module::port_t;
ptmp->name = perm_string();
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = wtmp;
delete $1;
$$ = ptmp;
}
| IDENTIFIER '[' expression ':' expression ']'
{ if (!pform_expression_is_constant($3)) {
yyerror(@3, "error: msb expression of "
"port part select must be constant.");
}
if (!pform_expression_is_constant($5)) {
yyerror(@5, "error: lsb expression of "
"port part select must be constant.");
}
index_component_t itmp;
itmp.sel = index_component_t::SEL_PART;
itmp.msb = $3;
itmp.lsb = $5;
| IDENTIFIER '[' expression ']'
{ PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) {
yyerror(@3, "error: port bit select "
"must be constant.");
}
tmp->msb_ = $3;
Module::port_t*ptmp = new Module::port_t;
ptmp->name = perm_string();
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = tmp;
delete $1;
$$ = ptmp;
}
name_component_t ntmp (lex_strings.make($1));
ntmp.index.push_back(itmp);
| IDENTIFIER '[' error ']'
{ yyerror(@1, "error: invalid port bit select");
Module::port_t*ptmp = new Module::port_t;
PEIdent*wtmp = new PEIdent(hname_t($1));
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
ptmp->name = lex_strings.make($1);
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = wtmp;
delete $1;
$$ = ptmp;
}
;
pform_name_t pname;
pname.push_back(ntmp);
PEIdent*wtmp = new PEIdent(pname);
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
Module::port_t*ptmp = new Module::port_t;
ptmp->name = perm_string();
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = wtmp;
delete $1;
$$ = ptmp;
}
| IDENTIFIER '[' expression ']'
{ if (!pform_expression_is_constant($3)) {
yyerror(@3, "error: port bit select "
"must be constant.");
}
index_component_t itmp;
itmp.sel = index_component_t::SEL_BIT;
itmp.msb = $3;
itmp.lsb = 0;
name_component_t ntmp (lex_strings.make($1));
ntmp.index.push_back(itmp);
pform_name_t pname;
pname.push_back(ntmp);
PEIdent*tmp = new PEIdent(pname);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
Module::port_t*ptmp = new Module::port_t;
ptmp->name = perm_string();
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = tmp;
delete $1;
$$ = ptmp;
}
| IDENTIFIER '[' error ']'
{ yyerror(@1, "error: invalid port bit select");
Module::port_t*ptmp = new Module::port_t;
PEIdent*wtmp = new PEIdent(lex_strings.make($1));
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
ptmp->name = lex_strings.make($1);
ptmp->expr = svector<PEIdent*>(1);
ptmp->expr[0] = wtmp;
delete $1;
$$ = ptmp;
}
;
port_reference_list
@@ -2760,25 +2759,38 @@ spec_polarity
;
spec_reference_event
: K_posedge expression
{ delete $2; }
| K_negedge expression
{ delete $2; }
| K_posedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| K_negedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| expr_primary K_TAND expression
{ delete $1;
delete $3;
}
| expr_primary
{ delete $1; }
;
: K_posedge expression
{ delete $2; }
| K_negedge expression
{ delete $2; }
| K_posedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| K_negedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| K_edge '[' edge_descriptor_list ']' expr_primary K_TAND expression
{ delete $5;
delete $7;
}
| expr_primary K_TAND expression
{ delete $1;
delete $3;
}
| expr_primary
{ delete $1; }
;
/* The edge_descriptor is detected by the lexor as the various
2-letter edge sequences that are supported here. For now, we
don't care what they are, because we do not yet support specify
edge events. */
edge_descriptor_list
: edge_descriptor_list ',' K_edge_descriptor
| K_edge_descriptor
;
spec_notifier_opt
: /* empty */
@@ -2789,16 +2801,12 @@ spec_notifier_opt
spec_notifier
: ','
{ }
| ',' identifier
| ',' heirarchy_identifier
{ delete $2; }
| spec_notifier ','
{ }
| spec_notifier ',' identifier
| spec_notifier ',' heirarchy_identifier
{ delete $3; }
| spec_notifier ',' identifier '[' expr_primary ']'
{ delete $3;
delete $5;
}
| IDENTIFIER
{ delete $1; }
;
@@ -2915,14 +2923,14 @@ statement
$$ = tmp;
}
| K_disable identifier ';'
| K_disable heirarchy_identifier ';'
{ PDisable*tmp = new PDisable(*$2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $2;
$$ = tmp;
}
| K_TRIGGER identifier ';'
| K_TRIGGER heirarchy_identifier ';'
{ PTrigger*tmp = new PTrigger(*$2);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
@@ -3130,7 +3138,7 @@ statement
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' expression_list_with_nuls ')' ';'
{ PCallTask*tmp = new PCallTask(hname_t($1), *$3);
{ PCallTask*tmp = new PCallTask(lex_strings.make($1), *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
@@ -3139,13 +3147,13 @@ statement
}
| SYSTEM_IDENTIFIER ';'
{ svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask(hname_t($1), pt);
PCallTask*tmp = new PCallTask(lex_strings.make($1), pt);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| identifier '(' expression_list_proper ')' ';'
| heirarchy_identifier '(' expression_list_proper ')' ';'
{ PCallTask*tmp = new PCallTask(*$1, *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
@@ -3158,7 +3166,7 @@ statement
between parentheses, but it seems natural, and people commonly
want it. So accept it explicitly. */
| identifier '(' ')' ';'
| heirarchy_identifier '(' ')' ';'
{ svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask(*$1, pt);
tmp->set_file(@1.text);
@@ -3166,7 +3174,7 @@ statement
delete $1;
$$ = tmp;
}
| identifier ';'
| heirarchy_identifier ';'
{ svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask(*$1, pt);
tmp->set_file(@1.text);
@@ -3521,7 +3529,7 @@ udp_sequ_entry
udp_initial
: K_initial IDENTIFIER '=' number ';'
{ PExpr*etmp = new PENumber($4);
PEIdent*itmp = new PEIdent(hname_t($2));
PEIdent*itmp = new PEIdent(lex_strings.make($2));
PAssign*atmp = new PAssign(itmp, etmp);
atmp->set_file(@2.text);
atmp->set_lineno(@2.first_line);
@@ -3586,37 +3594,40 @@ udp_output_sym
| '-' { $$ = '-'; }
;
/* Port declarations create wires for the inputs and the output. The
makes for these ports are scoped within the UDP, so there is no
heirarchy involved. */
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,
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,
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,
IVL_VT_LOGIC);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
$$ = tmp;
}
;
: K_input list_of_identifiers ';'
{ $$ = pform_make_udp_input_ports($2); }
| K_output IDENTIFIER ';'
{ pform_name_t pname;
pname.push_back(name_component_t(lex_strings.make($2)));
PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
$$ = tmp;
delete $2;
}
| K_reg IDENTIFIER ';'
{ pform_name_t pname;
pname.push_back(name_component_t(lex_strings.make($2)));
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
$$ = tmp;
delete $2;
}
| K_reg K_output IDENTIFIER ';'
{ pform_name_t pname;
pname.push_back(name_component_t(lex_strings.make($3)));
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
$$ = tmp;
delete $3;
}
;
udp_port_decls
: udp_port_decl
+73 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2007 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,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.144 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: pform.cc,v 1.148 2007/06/12 04:05:45 steve Exp $"
#endif
# include "config.h"
@@ -33,6 +33,7 @@
# include <list>
# include <map>
# include <assert.h>
# include <stack>
# include <typeinfo>
# include <sstream>
@@ -80,35 +81,34 @@ static unsigned pform_timescale_line = 0;
* and named blocks causes scope to be pushed and popped. The module
* name is not included in this scope stack.
*
* The hier_name function, therefore, converts the name to the scope
* of the module currently in progress.
* The hier_name function, therefore, converts the name to the scoped
* name within the module currently in progress. It never includes an
* instance name.
*
* The scope stack does not include any scope created by a generate
* scheme.
*/
static hname_t scope_stack;
static pform_name_t scope_stack;
void pform_push_scope(char*name)
{
scope_stack.append(name);
scope_stack.push_back(name_component_t(lex_strings.make(name)));
}
void pform_pop_scope()
{
char*tmp = scope_stack.remove_tail_name();
assert(tmp);
free(tmp);
scope_stack.pop_back();
}
static hname_t hier_name(const char*tail)
static pform_name_t hier_name(const char*tail)
{
hname_t name = scope_stack;
name.append(tail);
pform_name_t name = scope_stack;
name.push_back(name_component_t(lex_strings.make(tail)));
return name;
}
static PWire*get_wire_in_module(const hname_t&name)
static PWire*get_wire_in_module(const pform_name_t&name)
{
/* Note that if we are processing a generate, then the
scope depth will be empty because generate schemes
@@ -278,7 +278,7 @@ Module::port_t* pform_module_port_reference(char*name,
unsigned lineno)
{
Module::port_t*ptmp = new Module::port_t;
PEIdent*tmp = new PEIdent(hname_t(name));
PEIdent*tmp = new PEIdent(lex_strings.make(name));
tmp->set_file(file);
tmp->set_lineno(lineno);
ptmp->name = lex_strings.make(name);
@@ -348,7 +348,7 @@ void pform_start_generate_for(const struct vlltype&li,
gen->set_lineno(li.first_line);
// For now, assume that generates do not nest.
assert(pform_cur_generate == 0);
gen->parent = pform_cur_generate;
pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_LOOP;
@@ -375,8 +375,13 @@ void pform_endgenerate()
assert(pform_cur_generate != 0);
assert(pform_cur_module);
pform_cur_module->generate_schemes.push_back(pform_cur_generate);
pform_cur_generate = 0;
PGenerate*cur = pform_cur_generate;
pform_cur_generate = cur->parent;
if (pform_cur_generate != 0)
pform_cur_generate->generates.push_back(cur);
else
pform_cur_module->generate_schemes.push_back(cur);
}
bool pform_expression_is_constant(const PExpr*ex)
@@ -512,9 +517,10 @@ void pform_make_udp(perm_string name, list<string>*parms,
map<string,PWire*> defs;
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
hname_t pname = (*decl)[idx]->path();
pform_name_t pname = (*decl)[idx]->path();
string port_name = peek_tail_name(pname).str();
if (PWire*cur = defs[pname.peek_name(0)]) {
if (PWire*cur = defs[port_name]) {
bool rc = true;
assert((*decl)[idx]);
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
@@ -527,7 +533,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
}
} else {
defs[pname.peek_name(0)] = (*decl)[idx];
defs[port_name] = (*decl)[idx];
}
}
@@ -673,7 +679,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
// Make the port list for the UDP
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
udp->ports[idx] = pins[idx]->path().peek_name(0);
udp->ports[idx] = peek_tail_name(pins[idx]->path());
process_udp_table(udp, table, file, lineno);
udp->initial = init;
@@ -757,7 +763,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
// Make the port list for the UDP
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
udp->ports[idx] = pins[idx]->path().peek_name(0);
udp->ports[idx] = peek_tail_name(pins[idx]->path());
assert(udp);
assert(table);
@@ -914,6 +920,14 @@ void pform_makegates(PGBuiltin::Type type,
* constraints, and sometimes different syntax. The X_modgate
* functions handle the instantiations of modules (and UDP objects) by
* making PGModule objects.
*
* The first pform_make_modgate handles the case of a module
* instantiated with ports passed by position. The "wires" is an
* ordered array of port expressions.
*
* The second pform_make_modgate handles the case of a module
* instantiated with ports passed by name. The "bind" argument is the
* ports matched with names.
*/
static void pform_make_modgate(perm_string type,
perm_string name,
@@ -986,7 +1000,11 @@ static void pform_make_modgate(perm_string type,
cur->set_parameters(overrides->by_order);
}
pform_cur_module->add_gate(cur);
if (pform_cur_generate)
pform_cur_generate->add_gate(cur);
else
pform_cur_module->add_gate(cur);
}
void pform_make_modgates(perm_string type,
@@ -1091,7 +1109,7 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
void pform_make_reginit(const struct vlltype&li,
const char*name, PExpr*expr)
{
const hname_t sname = hier_name(name);
const pform_name_t sname = hier_name(name);
PWire*cur = pform_cur_module->get_wire(sname);
if (cur == 0) {
VLerror(li, "internal error: reginit to non-register?");
@@ -1130,11 +1148,11 @@ void pform_module_define_port(const struct vlltype&li,
svector<PExpr*>*range,
svector<named_pexpr_t*>*attr)
{
hname_t name = hier_name(nm);
pform_name_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur) {
ostringstream msg;
msg << name << " definition conflicts with "
msg << nm << " definition conflicts with "
<< "definition at " << cur->get_line()
<< ".";
VLerror(msg.str().c_str());
@@ -1197,7 +1215,7 @@ void pform_makewire(const vlltype&li, const char*nm,
ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr)
{
hname_t name = hier_name(nm);
pform_name_t name = hier_name(nm);
PWire*cur = get_wire_in_module(name);
@@ -1207,7 +1225,7 @@ void pform_makewire(const vlltype&li, const char*nm,
bool rc = cur->set_wire_type(type);
if (rc == false) {
ostringstream msg;
msg << name << " definition conflicts with "
msg << nm << " definition conflicts with "
<< "definition at " << cur->get_line()
<< ".";
VLerror(msg.str().c_str());
@@ -1286,10 +1304,11 @@ void pform_makewire(const vlltype&li,
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);
perm_string first_name = lex_strings.make(first->name);
pform_name_t name = hier_name(first_name);
PWire*cur = get_wire_in_module(name);
if (cur != 0) {
PEIdent*lval = new PEIdent(hname_t(first->name));
PEIdent*lval = new PEIdent(first_name);
lval->set_file(li.text);
lval->set_lineno(li.first_line);
PGAssign*ass = pform_make_pgassign(lval, first->expr,
@@ -1307,7 +1326,7 @@ void pform_makewire(const vlltype&li,
void pform_set_port_type(perm_string nm, NetNet::PortType pt,
const char*file, unsigned lineno)
{
hname_t name = hier_name(nm);
pform_name_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_LOGIC);
@@ -1324,14 +1343,14 @@ void pform_set_port_type(perm_string nm, NetNet::PortType pt,
case NetNet::NOT_A_PORT:
cerr << file << ":" << lineno << ": error: "
<< "port " << name << " is not in the port list."
<< "port " << nm << " is not in the port list."
<< endl;
error_count += 1;
break;
default:
cerr << file << ":" << lineno << ": error: "
<< "port " << name << " already has a port declaration."
<< "port " << nm << " already has a port declaration."
<< endl;
error_count += 1;
break;
@@ -1392,7 +1411,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
; cur != names->end() ; cur ++ ) {
perm_string txt = *cur;
hname_t name = hier_name(txt);
pform_name_t name = hier_name(txt);
/* Look for a preexisting wire. If it exists, set the
port direction. If not, create it. */
@@ -1437,7 +1456,7 @@ void pform_set_function(perm_string name, PFunction*func)
void pform_set_attrib(perm_string name, perm_string key, char*value)
{
hname_t path (name);
pform_name_t path = hier_name(name);
if (PWire*cur = pform_cur_module->get_wire(path)) {
cur->attributes[key] = new PEString(value);
@@ -1530,7 +1549,7 @@ void pform_set_specparam(perm_string name, PExpr*expr)
pform_cur_module->specparams[name] = expr;
}
void pform_set_defparam(const hname_t&name, PExpr*expr)
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
{
assert(expr);
pform_cur_module->defparms[name] = expr;
@@ -1624,7 +1643,7 @@ void pform_set_port_type(const struct vlltype&li,
static void pform_set_reg_integer(const char*nm)
{
hname_t name = hier_name(nm);
pform_name_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::INTEGER,
@@ -1658,7 +1677,7 @@ void pform_set_reg_integer(list<perm_string>*names)
static void pform_set_reg_time(const char*nm)
{
hname_t name = hier_name(nm);
pform_name_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, IVL_VT_LOGIC);
@@ -1695,7 +1714,9 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
; cur != names->end()
; cur ++ ) {
perm_string txt = *cur;
PWire*pp = new PWire(hname_t(txt),
pform_name_t tmp;
tmp.push_back(name_component_t(txt));
PWire*pp = new PWire(tmp,
NetNet::IMPLICIT,
NetNet::PINPUT,
IVL_VT_LOGIC);
@@ -1769,6 +1790,19 @@ int pform_parse(const char*path, FILE*file)
/*
* $Log: pform.cc,v $
* Revision 1.148 2007/06/12 04:05:45 steve
* Put instantiated modules in the proper generated scope.
*
* Revision 1.147 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.146 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.145 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.144 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
+6 -2
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.90 2007/04/19 02:52:53 steve Exp $"
#ident "$Id: pform.h,v 1.91 2007/05/24 04:07:12 steve Exp $"
#endif
# include "netlist.h"
@@ -261,7 +261,7 @@ extern void pform_set_localparam(perm_string name,
bool signed_flag,
svector<PExpr*>*range,
PExpr*expr);
extern void pform_set_defparam(const hname_t&name, PExpr*expr);
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
/*
* Functions related to specify blocks.
@@ -340,6 +340,10 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.91 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.90 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
+87 -33
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.97 2007/03/07 00:38:15 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.101 2007/06/04 02:19:07 steve Exp $"
#endif
# include "config.h"
@@ -72,6 +72,65 @@ ostream& operator<< (ostream&o, PGate::strength_t str)
return o;
}
ostream& operator<< (ostream&out, perm_string that)
{
out << that.str();
return out;
}
ostream& operator<< (ostream&out, const index_component_t&that)
{
out << "[";
switch (that.sel) {
case index_component_t::SEL_BIT:
out << *that.msb;
break;
case index_component_t::SEL_PART:
out << *that.msb << ":" << *that.lsb;
break;
case index_component_t::SEL_IDX_UP:
out << *that.msb << "+:" << *that.lsb;
break;
case index_component_t::SEL_IDX_DO:
out << *that.msb << "-:" << *that.lsb;
break;
default:
out << "???";
break;
}
out << "]";
return out;
}
ostream& operator<< (ostream&out, const name_component_t&that)
{
out << that.name.str();
typedef std::list<index_component_t>::const_iterator index_it_t;
for (index_it_t idx = that.index.begin()
; idx != that.index.end() ; idx++) {
out << *idx;
}
return out;
}
ostream& operator<< (ostream&o, const pform_name_t&that)
{
pform_name_t::const_iterator cur;
cur = that.begin();
o << *cur;
cur++;
while (cur != that.end()) {
o << "." << *cur;
cur++;
}
return o;
}
void PExpr::dump(ostream&out) const
{
out << typeid(*this).name();
@@ -145,29 +204,6 @@ void PENumber::dump(ostream&out) const
void PEIdent::dump(ostream&out) const
{
out << path_;
if (msb_) {
out << "[" << *msb_;
if (lsb_) switch (sel_) {
case SEL_IDX_UP:
out << "+:" << *lsb_;
break;
case SEL_IDX_DO:
out << "-:" << *lsb_;
break;
case SEL_PART:
out << ":" << *lsb_;
break;
default:
out << ":?:" << *lsb_;
break;
}
out << "]";
}
typedef std::vector<PExpr*>::const_iterator vector_it_t;
for (vector_it_t cur = idx_.begin() ; cur != idx_.end() ; cur++) {
out << "[" << *(*cur) << "]";
}
}
void PEString::dump(ostream&out) const
@@ -787,9 +823,9 @@ void PSpecPath::dump(std::ostream&out, unsigned ind) const
out << ");" << endl;
}
void PGenerate::dump(ostream&out) const
void PGenerate::dump(ostream&out, unsigned indent) const
{
out << " generate(" << id_number << ")";
out << setw(indent) << "" << "generate(" << id_number << ")";
switch (scheme_type) {
case GS_NONE:
@@ -811,20 +847,25 @@ void PGenerate::dump(ostream&out) const
out << endl;
for (map<hname_t,PWire*>::const_iterator idx = wires.begin()
for (map<pform_name_t,PWire*>::const_iterator idx = wires.begin()
; idx != wires.end() ; idx++) {
(*idx).second->dump(out, 6);
(*idx).second->dump(out, indent+2);
}
for (list<PGate*>::const_iterator idx = gates.begin()
; idx != gates.end() ; idx++) {
(*idx)->dump(out, 6);
(*idx)->dump(out, indent+2);
}
for (list<PProcess*>::const_iterator idx = behaviors.begin()
; idx != behaviors.end() ; idx++) {
(*idx)->dump(out, 6);
(*idx)->dump(out, indent+2);
}
for (list<PGenerate*>::const_iterator idx = generates.begin()
; idx != generates.end() ; idx++) {
(*idx)->dump(out, indent+2);
}
out << " endgenerate" << endl;
@@ -866,7 +907,7 @@ void Module::dump(ostream&out) const
}
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
typedef map<hname_t,PExpr*>::const_iterator parm_hiter_t;
typedef map<pform_name_t,PExpr*>::const_iterator parm_hiter_t;
for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
out << " parameter ";
@@ -904,7 +945,7 @@ void Module::dump(ostream&out) const
typedef list<PGenerate*>::const_iterator genscheme_iter_t;
for (genscheme_iter_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur++) {
(*cur)->dump(out);
(*cur)->dump(out, 4);
}
typedef map<perm_string,PExpr*>::const_iterator specparm_iter_t;
@@ -931,7 +972,7 @@ void Module::dump(ostream&out) const
}
// Iterate through and display all the wires.
for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
for (map<pform_name_t,PWire*>::const_iterator wire = wires_.begin()
; wire != wires_.end()
; wire ++ ) {
@@ -1032,6 +1073,19 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.101 2007/06/04 02:19:07 steve
* Handle bit/part select of array words in nets.
*
* Revision 1.100 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.99 2007/05/31 18:35:50 steve
* Missing return value to perm_string dump
*
* Revision 1.98 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.97 2007/03/07 00:38:15 steve
* Lint fixes.
*
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_types.cc,v 1.1 2007/05/24 04:07:12 steve Exp $"
#endif
# include "pform_types.h"
bool operator < (const name_component_t&lef, const name_component_t&rig)
{
if (lef.name < rig.name)
return true;
return false;
}
+74
View File
@@ -0,0 +1,74 @@
#ifndef __pform_types_H
#define __pform_types_H
/*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_types.h,v 1.2 2007/06/04 02:19:07 steve Exp $"
#endif
// This for the perm_string type.
# include "StringHeap.h"
# include <iostream>
# include <list>
/*
* parse-form types.
*/
struct index_component_t {
enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO };
index_component_t() : sel(SEL_NONE), msb(0), lsb(0) { };
~index_component_t() { }
ctype_t sel;
class PExpr*msb;
class PExpr*lsb;
};
struct name_component_t {
explicit name_component_t(perm_string n) : name(n) { }
~name_component_t() { }
perm_string name;
std::list<index_component_t>index;
};
extern bool operator < (const name_component_t&lef, const name_component_t&rig);
/*
* The pform_name_t is the general form for a heirarchical identifier.
*/
typedef std::list<name_component_t> pform_name_t;
inline perm_string peek_head_name(const pform_name_t&that)
{
return that.front().name;
}
inline perm_string peek_tail_name(const pform_name_t&that)
{
return that.back().name;
}
extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
#endif
+24 -15
View File
@@ -17,17 +17,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: symbol_search.cc,v 1.4 2007/01/16 05:44:15 steve Exp $"
#ident "$Id: symbol_search.cc,v 1.7 2007/06/02 03:42:13 steve Exp $"
#endif
# include "netlist.h"
# include "netmisc.h"
# include <assert.h>
/*
* Search for the hierarchical name.
*/
NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
NetScope*symbol_search(Design*des, NetScope*scope, pform_name_t path,
NetNet*&net,
const NetExpr*&par,
NetEvent*&eve,
@@ -36,7 +37,8 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
assert(scope);
/* Get the tail name of the object we are looking for. */
char*key = path.remove_tail_name();
perm_string key = peek_tail_name(path);
path.pop_back();
/* Initialize output argument to cleared. */
net = 0;
@@ -45,24 +47,21 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
/* If the path has a scope part, then search for the specified
scope that we are supposed to search. */
if (path.peek_name(0))
scope = des->find_scope(scope, path);
if (! path.empty()) {
list<hname_t> path_list = eval_scope_path(des, scope, path);
assert(path_list.size() == path.size());
scope = des->find_scope(scope, path_list);
}
while (scope) {
if ( (net = scope->find_signal(key)) ) {
delete key;
if ( (net = scope->find_signal(key)) )
return scope;
}
if ( (eve = scope->find_event(key)) ) {
delete key;
if ( (eve = scope->find_event(key)) )
return scope;
}
if ( (par = scope->get_parameter(key, ex1, ex2)) ) {
delete key;
if ( (par = scope->get_parameter(key, ex1, ex2)) )
return scope;
}
if (scope->type() == NetScope::MODULE)
scope = 0;
@@ -70,12 +69,22 @@ NetScope*symbol_search(const Design*des, NetScope*scope, hname_t path,
scope = scope->parent();
}
delete key;
return 0;
}
/*
* $Log: symbol_search.cc,v $
* Revision 1.7 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.5 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
+7 -2
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-proc.cc,v 1.70 2007/04/04 01:50:38 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.71 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -131,7 +131,7 @@ bool dll_target::func_def(const NetScope*net)
}
cerr << "?:0" << ": internal error: "
<< "Function " << net->name() << " has a return type"
<< "Function " << net->basename() << " has a return type"
<< " that I do not understand." << endl;
return false;
@@ -641,6 +641,8 @@ bool dll_target::proc_wait(const NetEvWait*net)
ivl_scope_t ev_scope = lookup_scope_(ev->scope());
ivl_event_t ev_tmp=0;
assert(ev_scope);
assert(ev_scope->nevent_ > 0);
for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) {
const char*ename = ivl_event_basename(ev_scope->event_[idx]);
if (strcmp(ev->name(), ename) == 0) {
@@ -735,6 +737,9 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.71 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.70 2007/04/04 01:50:38 steve
* t-dll should not canonicalize word addresses, elaboration already does it.
*
+67 -36
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.170 2007/04/02 01:12:34 steve Exp $"
#ident "$Id: t-dll.cc,v 1.171 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -134,6 +134,17 @@ inline static const char *basename(ivl_scope_t scope, const char *inst)
return inst+1;
}
static perm_string make_scope_name(const hname_t&name)
{
if (! name.has_number())
return name.peek_name();
char buf[1024];
snprintf(buf, sizeof buf, "%s[%d]",
name.peek_name().str(), name.peek_number());
return lex_strings.make(buf);
}
static struct dll_target dll_target_obj;
static void drive_from_link(const Link&lnk, ivl_drive_t&drv0, ivl_drive_t&drv1)
@@ -212,6 +223,7 @@ ivl_attribute_s* dll_target::fill_in_attributes(const Attrib*net)
static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur)
{
ivl_scope_t parent, tmp;
perm_string cur_name = make_scope_name(cur->fullname());
if (const NetScope*par = cur->parent()) {
parent = find_scope_from_root(root, par);
@@ -219,11 +231,11 @@ static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur)
return 0;
for (tmp = parent->child_ ; tmp ; tmp = tmp->sibling_)
if (strcmp(tmp->name_, cur->basename()) == 0)
if (strcmp(tmp->name_, cur_name) == 0)
return tmp;
} else {
if (strcmp(root->name_, cur->basename()) == 0)
if (strcmp(root->name_, cur_name) == 0)
return root;
}
@@ -442,7 +454,7 @@ ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope,
*/
void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
{
scope->nparam_ = net->parameters.size();
scope->nparam_ = net->parameters.size() + net->localparams.size();
if (scope->nparam_ == 0) {
scope->param_ = 0;
return;
@@ -462,37 +474,52 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
cur_par->scope = scope;
NetExpr*etmp = (*cur_pit).second.expr;
if (const NetEConst*e = dynamic_cast<const NetEConst*>(etmp)) {
expr_const(e);
assert(expr_);
switch (expr_->type_) {
case IVL_EX_STRING:
expr_->u_.string_.parameter = cur_par;
break;
case IVL_EX_NUMBER:
expr_->u_.number_.parameter = cur_par;
break;
default:
assert(0);
}
} else if (const NetECReal*e = dynamic_cast<const NetECReal*>(etmp)) {
expr_creal(e);
assert(expr_);
assert(expr_->type_ == IVL_EX_REALNUM);
expr_->u_.real_.parameter = cur_par;
}
cur_par->value = expr_;
expr_ = 0;
make_scope_param_expr(cur_par, etmp);
idx += 1;
}
for (pit_t cur_pit = net->localparams.begin()
; cur_pit != net->localparams.end() ; cur_pit ++) {
assert(idx < scope->nparam_);
ivl_parameter_t cur_par = scope->param_ + idx;
cur_par->basename = (*cur_pit).first;
cur_par->scope = scope;
NetExpr*etmp = (*cur_pit).second.expr;
make_scope_param_expr(cur_par, etmp);
idx += 1;
}
}
void dll_target::make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp)
{
if (const NetEConst*e = dynamic_cast<const NetEConst*>(etmp)) {
expr_const(e);
assert(expr_);
switch (expr_->type_) {
case IVL_EX_STRING:
expr_->u_.string_.parameter = cur_par;
break;
case IVL_EX_NUMBER:
expr_->u_.number_.parameter = cur_par;
break;
default:
assert(0);
}
} else if (const NetECReal*e = dynamic_cast<const NetECReal*>(etmp)) {
expr_creal(e);
assert(expr_);
assert(expr_->type_ == IVL_EX_REALNUM);
expr_->u_.real_.parameter = cur_par;
}
cur_par->value = expr_;
expr_ = 0;
}
void dll_target::add_root(ivl_design_s &des_, const NetScope *s)
@@ -1951,8 +1978,9 @@ void dll_target::scope(const NetScope*net)
assert(scope);
} else {
perm_string sname = make_scope_name(net->fullname());
scope = new struct ivl_scope_s;
scope->name_ = net->basename();
scope->name_ = sname;
scope->child_ = 0;
scope->sibling_ = 0;
scope->parent = find_scope(des_, net->parent());
@@ -1985,12 +2013,12 @@ void dll_target::scope(const NetScope*net)
}
assert(def);
scope->type_ = IVL_SCT_TASK;
scope->tname_ = strings_.make(def->name().c_str());
scope->tname_ = def->scope()->basename();
break;
}
case NetScope::FUNC:
scope->type_ = IVL_SCT_FUNCTION;
scope->tname_ = strings_.make(net->func_def()->name().c_str());
scope->tname_ = net->func_def()->scope()->basename();
break;
case NetScope::BEGIN_END:
scope->type_ = IVL_SCT_BEGIN;
@@ -2227,6 +2255,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.171 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.170 2007/04/02 01:12:34 steve
* Seperate arrayness from word count
*
+5 -1
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.142 2007/04/02 01:12:34 steve Exp $"
#ident "$Id: t-dll.h,v 1.143 2007/06/02 03:42:13 steve Exp $"
#endif
# include "target.h"
@@ -165,6 +165,7 @@ struct dll_target : public target_t, public expr_scan_t {
void make_logic_delays_(struct ivl_net_logic_s*obj, const NetObj*net);
void make_scope_parameters(ivl_scope_t scope, const NetScope*net);
void make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp);
static ivl_expr_t expr_from_value_(const verinum&that);
};
@@ -679,6 +680,9 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.143 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.142 2007/04/02 01:12:34 steve
* Seperate arrayness from word count
*
+5 -2
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.80 2007/01/16 05:44:16 steve Exp $"
#ident "$Id: target.cc,v 1.81 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -38,7 +38,7 @@ void target_t::scope(const NetScope*)
void target_t::event(const NetEvent*ev)
{
cerr << ev->get_line() << ": error: target (" << typeid(*this).name()
<< "): Unhandled event <" << ev->full_name() << ">." << endl;
<< "): Unhandled event <" << ev->name() << ">." << endl;
}
bool target_t::signal_paths(const NetNet*)
@@ -429,6 +429,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.81 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.80 2007/01/16 05:44:16 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
+8 -2
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.147 2007/03/02 06:13:22 steve Exp $"
#ident "$Id: stub.c,v 1.148 2007/06/12 02:23:40 steve Exp $"
#endif
/*
@@ -1231,6 +1231,9 @@ static void show_logic(ivl_net_logic_t net)
case IVL_LO_OR:
fprintf(out, " or %s", name);
break;
case IVL_LO_PMOS:
fprintf(out, " pmos %s", name);
break;
case IVL_LO_PULLDOWN:
fprintf(out, " pulldown %s", name);
break;
@@ -1247,7 +1250,7 @@ static void show_logic(ivl_net_logic_t net)
break;
default:
fprintf(out, " unsupported gate %s", name);
fprintf(out, " unsupported gate<type=%d> %s", ivl_logic_type(net), name);
break;
}
@@ -1491,6 +1494,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.148 2007/06/12 02:23:40 steve
* displan pmos gates.
*
* Revision 1.147 2007/03/02 06:13:22 steve
* Add support for edge sensitive spec paths.
*
+2 -2
View File
@@ -21,8 +21,8 @@ AX_CPP_PRECOMP
# Do some more operating system specific setup.
case "${host}" in
*-*-linux*)
AC_DEFINE(_LARGEFILE_SOURCE)
AC_DEFINE(_LARGEFILE64_SOURCE)
AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
AC_DEFINE([_LARGEFILE64_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
;;
esac
+31 -7
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.20 2007/02/26 19:49:50 steve Exp $"
#ident "$Id: eval_real.c,v 1.22 2007/06/12 02:36:58 steve Exp $"
#endif
/*
@@ -142,6 +142,17 @@ static int draw_realnum_real(ivl_expr_t exp)
unsigned long mant;
int sign = 0;
/* Handle the special case that the value is +-inf. */
if (isinf(value)) {
if (value > 0)
fprintf(vvp_out, " %%loadi/wr %d, 0, %d; load=+inf\n",
res, 0x3fff);
else
fprintf(vvp_out, " %%loadi/wr %d, 0, %d; load=-inf\n",
res, 0x7fff);
return res;
}
if (value < 0) {
sign = 0x4000;
value *= -1;
@@ -188,6 +199,7 @@ static int draw_sfunc_real(ivl_expr_t exp)
{
struct vector_info sv;
int res;
const char*sign_flag = "";
switch (ivl_expr_value(exp)) {
@@ -209,9 +221,12 @@ static int draw_sfunc_real(ivl_expr_t exp)
sv = draw_eval_expr(exp, 0);
clr_vector(sv);
if (ivl_expr_signed(exp))
sign_flag = "/s";
res = allocate_word();
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n",
res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
break;
@@ -232,8 +247,10 @@ static int draw_signal_real_logic(ivl_expr_t exp)
{
int res = allocate_word();
struct vector_info sv = draw_eval_expr(exp, 0);
const char*sign_flag = ivl_expr_signed(exp)? "/s" : "";
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n", res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u; logic signal as real\n",
sign_flag, res, sv.base, sv.wid);
clr_vector(sv);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
@@ -394,14 +411,15 @@ int draw_eval_real(ivl_expr_t exp)
default:
if (ivl_expr_value(exp) == IVL_VT_VECTOR) {
struct vector_info sv = draw_eval_expr(exp, 0);
const char*sign_flag = ivl_expr_signed(exp)? "/s" : "";
clr_vector(sv);
res = allocate_word();
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n", res,
sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
} else {
fprintf(stderr, "XXXX Evaluate real expression (%d)\n",
@@ -419,6 +437,12 @@ int draw_eval_real(ivl_expr_t exp)
/*
* $Log: eval_real.c,v $
* Revision 1.22 2007/06/12 02:36:58 steve
* handle constant inf values.
*
* Revision 1.21 2007/06/07 03:20:15 steve
* Properly handle signed conversion to real
*
* Revision 1.20 2007/02/26 19:49:50 steve
* Spelling fixes (larry doolittle)
*
+5 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: util.h,v 1.8 2005/11/27 17:01:57 steve Exp $"
#ident "$Id: util.h,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include <map>
@@ -46,11 +46,13 @@ struct attrib_list_t {
extern attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
const Design*des,
NetScope*scope);
Design*des, NetScope*scope);
/*
* $Log: util.h,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
+4 -4
View File
@@ -1,14 +1,14 @@
Summary: Icarus Verilog
Name: verilog
Version: 0.9.0.20070421
Version: 0.9.0.20070608
Release: 0
License: GPL
Group: Productivity/Scientific/Electronics
Source: verilog-20070421.tar.gz
Source: verilog-20070608.tar.gz
URL: http://www.icarus.com/eda/verilog/index.html
Packager: Stephen Williams <[email protected]>
BuildRoot: %{_tmppath}/%{name}-%{version}-20070421-%{release}-root
BuildRoot: %{_tmppath}/%{name}-%{version}-20070608-%{release}-root
BuildRequires: gcc-c++, zlib-devel, bison, flex, gperf, readline-devel
@@ -32,7 +32,7 @@ engineering formats, including simulation. It strives to be true
to the IEEE-1364 standard.
%prep
%setup -n verilog-20070421
%setup -n verilog-20070608
%build
%ifarch x86_64
+1 -1
View File
@@ -67,7 +67,7 @@ AX_CPP_PRECOMP
file64_support=''
case "${host}" in
*-*-linux*)
AC_DEFINE(_LARGEFILE_SOURCE)
AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
file64_support='-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64'
;;
esac
+5 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: codes.h,v 1.83 2007/04/14 04:43:02 steve Exp $"
#ident "$Id: codes.h,v 1.84 2007/06/07 03:20:15 steve Exp $"
#endif
@@ -80,6 +80,7 @@ extern bool of_FORK(vthread_t thr, vvp_code_t code);
extern bool of_INV(vthread_t thr, vvp_code_t code);
extern bool of_IX_ADD(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET_S(vthread_t thr, vvp_code_t code);
extern bool of_IX_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_IX_MUL(vthread_t thr, vvp_code_t code);
extern bool of_IX_SUB(vthread_t thr, vvp_code_t code);
@@ -186,6 +187,9 @@ extern vvp_code_t codespace_null(void);
/*
* $Log: codes.h,v $
* Revision 1.84 2007/06/07 03:20:15 steve
* Properly handle signed conversion to real
*
* Revision 1.83 2007/04/14 04:43:02 steve
* Finish up part select of array words.
*
+5 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.231 2007/04/14 04:43:02 steve Exp $"
#ident "$Id: compile.cc,v 1.232 2007/06/07 03:20:16 steve Exp $"
#endif
# include "arith.h"
@@ -125,6 +125,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/get/s",of_IX_GET_S,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/load",of_IX_LOAD,2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/mul", of_IX_MUL, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/sub", of_IX_SUB, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
@@ -1624,6 +1625,9 @@ void compile_param_string(char*label, char*name, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.232 2007/06/07 03:20:16 steve
* Properly handle signed conversion to real
*
* Revision 1.231 2007/04/14 04:43:02 steve
* Finish up part select of array words.
*
+14 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: config.h.in,v 1.23 2007/02/02 04:33:01 steve Exp $"
#ident "$Id: config.h.in,v 1.24 2007/06/13 01:03:57 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -50,6 +50,7 @@
# undef HAVE_READLINE_HISTORY_H
# undef HAVE_INTTYPES_H
# undef HAVE_LROUND
# undef HAVE_NAN
/* Figure if I can use readline. */
#undef USE_READLINE
@@ -85,6 +86,8 @@ typedef unsigned long vvp_time64_t;
# endif
#endif
# include <math.h>
/* getrusage, /proc/self/statm */
# undef HAVE_SYS_RESOURCE_H
@@ -98,6 +101,13 @@ extern long lround(double x);
#endif
#endif
#if !defined(HAVE_NAN)
# define nan(x) (NAN)
#endif
#if !defined(INFINITY)
# define INFINITY HUGE_VAL
#endif
/*
* When doing dynamic linking, we need a uniform way to identify the
@@ -119,6 +129,9 @@ extern long lround(double x);
/*
* $Log: config.h.in,v $
* Revision 1.24 2007/06/13 01:03:57 steve
* Detect and use the nan function.
*
* Revision 1.23 2007/02/02 04:33:01 steve
* Use inttypes.h instead of stdint.h for portability.
*
+2 -2
View File
@@ -75,13 +75,13 @@ esac
# Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support.
AC_CHECK_FUNCS(lround)
AC_CHECK_FUNCS(lround nan)
# see how we can give some resource usage stats with -v
# Linux does not provide mem stats in rusage, use /proc/self/statm.
AC_CHECK_HEADERS(sys/resource.h)
case "${host}" in *linux*) AC_DEFINE(LINUX) ;; esac
case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac
# Linker option used when compiling the target
AX_LD_RDYNAMIC
+6 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: npmos.cc,v 1.13 2005/06/22 00:04:49 steve Exp $"
#ident "$Id: npmos.cc,v 1.14 2007/06/12 02:25:00 steve Exp $"
#endif
# include "npmos.h"
@@ -76,7 +76,8 @@ void vvp_fun_pmos_::generate_output_(vvp_net_ptr_t ptr)
}
}
vvp_send_vec8(ptr.ptr()->out, out);
if (out.size() > 0)
vvp_send_vec8(ptr.ptr()->out, out);
}
@@ -120,6 +121,9 @@ void vvp_fun_rpmos::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
/*
* $Log: npmos.cc,v $
* Revision 1.14 2007/06/12 02:25:00 steve
* Do not propogate until initialized.
*
* Revision 1.13 2005/06/22 00:04:49 steve
* Reduce vvp_vector4 copies by using const references.
*
+9 -3
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2001-2003 Stephen Williams ([email protected])
*
* $Id: opcodes.txt,v 1.76 2007/04/14 04:43:02 steve Exp $
* $Id: opcodes.txt,v 1.78 2007/06/12 02:36:58 steve Exp $
*/
@@ -306,6 +306,7 @@ bit:
* %ix/get <idx>, <bit>, <wid>
* %ix/get/s <idx>, <bit>, <wid>
This instruction loads a thread vector starting at <bit>, size <wid>,
into the index register <idx>. The <bit> is the lsb of the value in
@@ -313,7 +314,9 @@ thread bit space, and <wid> is the width of the vector.
The function converts the 4-value bits into a binary number, without
sign extension. If any of the bits of the vector is x or z, then the
index register gets the value 0.
index register gets the value 0. The %ix/get/s is the same, except
that it assumes the source vector is sign extended to fit the index
register.
The function also writes into bit 4 a 1 if any of the bits of the
input vector are x or z. This is a flag that the 0 value written into
@@ -430,9 +433,12 @@ auto-increment feature.
This opcode loads an immediate value, floating point, into the word
register selected by <bit>. The mantissa is an unsigned integer value,
up to 32 bits, that multiplied by 2**(<exp>-0x1000) to make a real
value. The sign bit is OR-ed into the <exp> value at bit 0x2000, and
value. The sign bit is OR-ed into the <exp> value at bit 0x4000, and
is removed from the <exp> before calculating the real value.
If <exp>==0x3fff and <mant> == 0, the value is +inf.
If <exp>==0x7fff and <mant> == 0, the value is -inf.
If <exp>--0x3fff and <mant> != 0, the value is NaN.
* %mod <bit-l>, <bit-r>, <wid>
* %mod/s <bit-l>, <bit-r>, <wid>
+79 -11
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vthread.cc,v 1.162 2007/04/14 04:43:02 steve Exp $"
#ident "$Id: vthread.cc,v 1.166 2007/06/13 01:03:57 steve Exp $"
#endif
# include "config.h"
@@ -1334,8 +1334,8 @@ bool of_DIV(vthread_t thr, vvp_code_t cp)
if (bit4_is_xz(lb) || bit4_is_xz(rb))
goto x_out;
lv |= lb << idx;
rv |= rb << idx;
lv |= (unsigned long) lb << idx;
rv |= (unsigned long) rb << idx;
idx1 += 1;
if (idx2 >= 4)
@@ -1815,7 +1815,7 @@ bool of_IX_GET(vthread_t thr, vvp_code_t cp)
break;
}
v |= vv << i;
v |= (unsigned long) vv << i;
if (base >= 4)
base += 1;
@@ -1828,6 +1828,46 @@ bool of_IX_GET(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_IX_GET_S(vthread_t thr, vvp_code_t cp)
{
unsigned index = cp->bit_idx[0];
unsigned base = cp->bit_idx[1];
unsigned width = cp->number;
unsigned long v = 0;
bool unknown_flag = false;
vvp_bit4_t vv = BIT4_0;
for (unsigned i = 0 ; i<width ; i += 1) {
vv = thr_get_bit(thr, base);
if (bit4_is_xz(vv)) {
v = 0UL;
unknown_flag = true;
break;
}
v |= (unsigned long) vv << i;
if (base >= 4)
base += 1;
}
/* Sign-extend to fill the integer value. */
if (!unknown_flag) {
unsigned long pad = vv;
for (unsigned i = width ; i < 8*sizeof(v) ; i += 1) {
v |= pad << i;
}
}
thr->words[index].w_int = v;
/* Set bit 4 as a flag if the input is unknown. */
thr_put_bit(thr, 4, unknown_flag? BIT4_1 : BIT4_0);
return true;
}
/*
* The various JMP instruction work simply by pulling the new program
@@ -2154,6 +2194,22 @@ bool of_LOADI_WR(vthread_t thr, vvp_code_t cp)
unsigned idx = cp->bit_idx[0];
double mant = cp->number;
int exp = cp->bit_idx[1];
// Detect +infinity
if (exp==0x3fff && cp->number==0) {
thr->words[idx].w_real = INFINITY;
return true;
}
// Detect -infinity
if (exp==0x7fff && cp->number==0) {
thr->words[idx].w_real = -INFINITY;
return true;
}
// Detect NaN
if ( (exp&0x3fff) == 0x3fff ) {
thr->words[idx].w_real = nan("");
}
double sign = (exp & 0x4000)? -1.0 : 1.0;
exp &= 0x1fff;
@@ -2304,8 +2360,8 @@ bool of_MOD(vthread_t thr, vvp_code_t cp)
if ((lb | rb) & 2)
goto x_out;
lv |= lb << idx;
rv |= rb << idx;
lv |= (unsigned long long) lb << idx;
rv |= (unsigned long long) rb << idx;
idx1 += 1;
if (idx2 >= 4)
@@ -2354,8 +2410,8 @@ bool of_MOD_S(vthread_t thr, vvp_code_t cp)
if ((lb | rb) & 2)
goto x_out;
lv |= lb << idx;
rv |= rb << idx;
lv |= (long long) lb << idx;
rv |= (long long) rb << idx;
idx1 += 1;
if (idx2 >= 4)
@@ -2487,8 +2543,8 @@ bool of_MUL(vthread_t thr, vvp_code_t cp)
if (bit4_is_xz(lb) || bit4_is_xz(rb))
goto x_out;
lv |= ((unsigned long)lb) << idx;
rv |= ((unsigned long)rb) << idx;
lv |= (unsigned long) lb << idx;
rv |= (unsigned long) rb << idx;
idx1 += 1;
if (idx2 >= 4)
@@ -2598,7 +2654,7 @@ bool of_MULI(vthread_t thr, vvp_code_t cp)
if (bit4_is_xz(lb))
goto x_out;
lv |= lb << idx;
lv |= (unsigned long) lb << idx;
idx1 += 1;
}
@@ -3433,6 +3489,18 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.166 2007/06/13 01:03:57 steve
* Detect and use the nan function.
*
* Revision 1.165 2007/06/12 02:36:58 steve
* handle constant inf values.
*
* Revision 1.164 2007/06/07 03:20:16 steve
* Properly handle signed conversion to real
*
* Revision 1.163 2007/06/05 21:52:22 steve
* int vs long expressions on 64bit arch (ldoolitt)
*
* Revision 1.162 2007/04/14 04:43:02 steve
* Finish up part select of array words.
*
+9 -4
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.cc,v 1.63 2007/04/15 02:07:24 steve Exp $"
#ident "$Id: vvp_net.cc,v 1.64 2007/06/12 02:36:58 steve Exp $"
# include "config.h"
# include "vvp_net.h"
@@ -630,6 +630,8 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag)
return true;
}
bool flag = true;
if (vec.value(vec.size()-1) != BIT4_1) {
signed_flag = false;
}
@@ -647,7 +649,7 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag)
res += pow(2.0, (int)idx);
break;
default:
return false;
flag = false;
}
}
res *= -1.0;
@@ -660,12 +662,12 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag)
res += pow(2.0, (int)idx);
break;
default:
return false;
flag = false;
}
}
}
val = res;
return true;
return flag;
}
template <class T> T coerce_to_width(const T&that, unsigned width)
@@ -2293,6 +2295,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
/*
* $Log: vvp_net.cc,v $
* Revision 1.64 2007/06/12 02:36:58 steve
* handle constant inf values.
*
* Revision 1.63 2007/04/15 02:07:24 steve
* Fix div/mod calculation that caused a hang for some divisions.
*
+8 -3
View File
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.h,v 1.57 2007/03/22 16:08:19 steve Exp $"
#ident "$Id: vvp_net.h,v 1.58 2007/06/12 02:36:58 steve Exp $"
# include "config.h"
# include <stddef.h>
@@ -254,8 +254,10 @@ template <class T> extern T coerce_to_width(const T&that, unsigned width);
/*
* These functions extract the value of the vector as a native type,
* if possible, and return true to indicate success. If the vector has
* any X or Z bits, the resulting value will be unchanged and the
* return value becomes false to indicate an error.
* any X or Z bits, the resulting value will have 0 bits in their
* place (this follows the rules of Verilog conversions from vector4
* to real and integers) and the return value becomes false to
* indicate an error.
*/
extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val);
extern bool vector4_to_value(const vvp_vector4_t&a, double&val, bool is_signed);
@@ -1040,6 +1042,9 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val,
/*
* $Log: vvp_net.h,v $
* Revision 1.58 2007/06/12 02:36:58 steve
* handle constant inf values.
*
* Revision 1.57 2007/03/22 16:08:19 steve
* Spelling fixes from Larry
*