mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-26 15:56:24 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87e813766a | ||
|
|
e24e77660f | ||
|
|
8ec6d9983d | ||
|
|
ae82eccdc4 | ||
|
|
fa18d9bc01 | ||
|
|
16ec4cb685 | ||
|
|
6f08f92ffc | ||
|
|
0a38499941 | ||
|
|
55f8e5d364 | ||
|
|
b631268f56 | ||
|
|
1a8ffe2a9c | ||
|
|
e4bcc87dc1 | ||
|
|
34111a25cb | ||
|
|
8fd42fbf61 | ||
|
|
129a064e1a | ||
|
|
c7d97f4146 | ||
|
|
1f9a246c6d | ||
|
|
17fd3bae15 | ||
|
|
29aa68302e | ||
|
|
8dcd09797f | ||
|
|
ddd36ecb6c | ||
|
|
67b1eee7ce | ||
|
|
629c6e9a40 | ||
|
|
6ea1337be0 | ||
|
|
b981c81d37 |
@@ -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.
|
||||
|
||||
@@ -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
@@ -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 \
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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)
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user