Compare commits

..
3 Commits
Author SHA1 Message Date
steve 61d230c5b2 Get memory word updates from trunk 2002-03-02 00:28:39 +00:00
steve 8f94545f2a cariage return fixes from main trunk. 2002-03-02 00:27:10 +00:00
steve 6975707804 Properly initialize code tables to 0. 2002-03-02 00:25:31 +00:00
514 changed files with 38711 additions and 93899 deletions
-8
View File
@@ -2,14 +2,9 @@ lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
@@ -17,11 +12,8 @@ configure
Makefile
check
check.cc
check.vvp
config.status
config.log
config.cache
autom4te.cache
config.h
_pli_types.h
dosify
+24 -31
View File
@@ -16,8 +16,8 @@
* 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: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#if !defined(WINNT)
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
@@ -36,8 +36,23 @@ Attrib::~Attrib()
delete[] list_;
}
void Attrib::set_attributes(const map<string,string>&attr)
{
assert(list_ == 0);
const verinum& Attrib::attribute(perm_string key) const
nlist_ = attr.size();
list_ = new cell_[nlist_];
map<string,string>::const_iterator idx;
unsigned jdx;
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
struct cell_*tmp = list_ + jdx;
tmp->key = (*idx).first;
tmp->val = (*idx).second;
}
}
string Attrib::attribute(const string&key) const
{
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
@@ -45,11 +60,10 @@ const verinum& Attrib::attribute(perm_string key) const
return list_[idx].val;
}
static const verinum null;
return null;
return "";
}
void Attrib::attribute(perm_string key, const verinum&value)
void Attrib::attribute(const string&key, const string&value)
{
unsigned idx;
@@ -78,7 +92,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
verinum tmp = attribute(that.list_[idx].key);
string tmp = attribute(that.list_[idx].key);
if (tmp != that.list_[idx].val)
return false;
}
@@ -86,18 +100,18 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
return true;
}
unsigned Attrib::attr_cnt() const
unsigned Attrib::size() const
{
return nlist_;
}
perm_string Attrib::attr_key(unsigned idx) const
string Attrib::key(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].key;
}
const verinum& Attrib::attr_value(unsigned idx) const
string Attrib::value(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].val;
@@ -106,27 +120,6 @@ const verinum& Attrib::attr_value(unsigned idx) const
/*
* $Log: Attrib.cc,v $
* Revision 1.6 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+12 -33
View File
@@ -18,12 +18,12 @@
* 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: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#if !defined(WINNT)
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
#endif
# include "StringHeap.h"
# include "verinum.h"
# include <string>
# include <map>
/*
* This class keeps a map of key/value pairs. The map can be set from
@@ -35,21 +35,21 @@ class Attrib {
Attrib();
~Attrib();
const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value);
void set_attributes(const map<string,string>&attr);
string attribute(const string&key) const;
void attribute(const string&key, const string&value);
bool has_compat_attributes(const Attrib&that) const;
/* Provide a means of iterating over the entries in the map. */
unsigned attr_cnt() const;
perm_string attr_key(unsigned idx) const;
const verinum& attr_value(unsigned idx) const;
unsigned size() const;
string key(unsigned idx) const;
string value(unsigned idx) const;
private:
struct cell_ {
perm_string key;
verinum val;
string key;
string val;
};
unsigned nlist_;
@@ -62,27 +62,6 @@ class Attrib {
/*
* $Log: Attrib.h,v $
* Revision 1.5 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
+4 -32
View File
@@ -16,7 +16,7 @@ compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Library version, and
- anything else you think relevant.
- anything else you think relevent.
Be aware that I do not have at my disposal a porting lab. I have the
alpha on my desk, and the Linux/Intel box with a logic analyzer and
@@ -104,30 +104,12 @@ module may not be needed as long as the ``-s <name>'' switch is
given.
So when you send a test case, ask yourself "Can poor overworked Steve
invoke the error without any Verilog other than what is included?" And
invoke the error without any Verilog other then what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
tracking system. Once you believe you have found a bug, you may browse
the bugs database for existing bugs that may be related to yours. You
might find that your bug has already been fixed in a later release or
snapshot. If that's the case, then you are set.
The bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
also browse the bug database, just to get an idea what is still
broken. You may for example find a related bug that explains your
symptom.
The root page of the bug report database describes how to submit your
completed bug report. You may submit it via the web form, or via
e-mail.
HOW TO SEND PATCHES
Bug reports with patches are very welcome, especially if they are
@@ -148,7 +130,7 @@ patch is for, I will ask for clarification before applying it.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
Icarus Verilog is Copyright (c) 1998-1999 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
@@ -159,18 +141,8 @@ then falls under the "otherwise noted" category.
I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
$Id: BUGS.txt,v 1.2 1999/08/06 04:05:28 steve Exp $
$Log: BUGS.txt,v $
Revision 1.5 2007/03/22 16:08:14 steve
Spelling fixes from Larry
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
Revision 1.3 2003/01/30 16:23:07 steve
Spelling fixes.
Revision 1.2 1999/08/06 04:05:28 steve
Handle scope of parameters.
+182 -66
View File
@@ -16,8 +16,8 @@
* 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: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT)
#ident "$Id: HName.cc,v 1.3 2002/01/05 04:36:06 steve Exp $"
#endif
# include "config.h"
@@ -29,114 +29,230 @@
# include <malloc.h>
#endif
hname_t::hname_t()
{
number_ = INT_MIN;
item_ = 0;
count_ = 0;
}
hname_t::hname_t(perm_string text)
hname_t::hname_t(const char*text)
{
name_ = text;
number_ = INT_MIN;
}
hname_t::hname_t(perm_string text, int num)
{
name_ = text;
number_ = num;
item_ = strdup(text);
count_ = 1;
}
hname_t::hname_t(const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
}
hname_t& hname_t::operator = (const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
return *this;
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;
}
}
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;
}
}
perm_string hname_t::peek_name(void) const
void hname_t::append(const char*text)
{
return name_;
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;
}
}
bool hname_t::has_number() const
void hname_t::prepend(const char*text)
{
return number_ != INT_MIN;
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;
}
}
int hname_t::peek_number() const
char* hname_t::remove_tail_name()
{
return number_;
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];
}
}
bool operator < (const hname_t&l, const hname_t&r)
{
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
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)
return false;
if (rc && !lc)
return true;
// Must be ==
return false;
}
bool operator == (const hname_t&l, const hname_t&r)
{
if (l.peek_name() == r.peek_name()) {
if (l.has_number() && r.has_number())
return l.peek_number() == r.peek_number();
else
return true;
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);
}
return false;
}
if (lc || rc)
return false;
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
// Must be ==
return true;
}
ostream& operator<< (ostream&out, const hname_t&that)
{
if (that.peek_name() == 0) {
switch (that.count_) {
case 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.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
+34 -47
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2007 Stephen Williams ([email protected])
* Copyright (c) 2001 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
@@ -18,79 +18,66 @@
* 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: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT)
#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $"
#endif
# include <iostream>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#endif
/*
* 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.
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
explicit hname_t (const char*text);
hname_t (const hname_t&that);
~hname_t();
hname_t& operator= (const 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);
// Return the string part of the hname_t.
perm_string peek_name(void) const;
// 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);
bool has_number() const;
int peek_number() 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;
friend ostream& operator<< (ostream&, const hname_t&);
private:
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_;
union {
char**array_;
char* item_;
};
unsigned count_;
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.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+6 -29
View File
@@ -16,19 +16,14 @@
* 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: LineInfo.cc,v 1.4 2003/01/17 05:49:03 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "LineInfo.h"
# include <sstream>
LineInfo::LineInfo()
: file_(0), lineno_(0)
{
}
# include <cstdio>
LineInfo::~LineInfo()
{
@@ -36,11 +31,9 @@ LineInfo::~LineInfo()
string LineInfo::get_line() const
{
ostringstream buf;
buf << (file_? file_ : "") << ":" << lineno_;
string res = buf.str();
return res;
char buf[8];
sprintf(buf, "%u", lineno_);
return string(file_? file_ : "") + ":" + buf;
}
void LineInfo::set_line(const LineInfo&that)
@@ -49,24 +42,8 @@ void LineInfo::set_line(const LineInfo&that)
lineno_ = that.lineno_;
}
void LineInfo::set_file(const char*f)
{
file_ = f;
}
void LineInfo::set_lineno(unsigned n)
{
lineno_ = n;
}
/*
* $Log: LineInfo.cc,v $
* Revision 1.4 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+5 -16
View File
@@ -18,14 +18,12 @@
* 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: LineInfo.h,v 1.8 2005/06/14 19:13:43 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
#endif
# include <string>
using namespace std;
/*
* This class holds line information for an internal object.
*
@@ -37,15 +35,15 @@ using namespace std;
class LineInfo {
public:
LineInfo();
LineInfo() : file_(0), lineno_(0) { }
~LineInfo();
string get_line() const;
void set_line(const LineInfo&that);
void set_file(const char*f);
void set_lineno(unsigned n);
void set_file(const char*f) { file_ = f; }
void set_lineno(unsigned n) { lineno_ = n; }
private:
const char* file_;
@@ -54,15 +52,6 @@ class LineInfo {
/*
* $Log: LineInfo.h,v $
* Revision 1.8 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.7 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
+110 -134
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.181 2007/05/24 04:07:11 steve Exp $"
#ident "$Id: Makefile.in,v 1.115 2002/02/16 03:18:53 steve Exp $"
#
#
SHELL = /bin/sh
@@ -25,7 +25,7 @@ SHELL = /bin/sh
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.9.devel
VERSION = 0.6
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -37,12 +37,11 @@ VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
mandir = @mandir@
libdir64 = @libdir64@
includedir = $(prefix)/include
dllib=@DLLIB@
rdynamic=@rdynamic@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
@@ -50,24 +49,40 @@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
LDFLAGS = @LDFLAGS@
all: dep ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
# The TARGETS variable lists the target modules that can be build and
# installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
ifeq ('@HAVE_IPAL@','yes')
TARGETS += tgt-pal
endif
ifeq (@ENABLE_VVM@,yes)
SUB_VVM = vvm
endif
all: ivl@EXEEXT@ libvpi.a
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) all); done
cd vpi ; $(MAKE) all
cd ivlpp ; $(MAKE) all
cd driver ; $(MAKE) VERSION=$(VERSION) all
cd tgt-verilog ; $(MAKE) all
cd tgt-stub ; $(MAKE) all
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@MING32@,yes)
all: dep dosify.exe
ifeq (@WIN32@,yes)
all: dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
endif
@@ -76,86 +91,86 @@ endif
# sure the basics were compiled properly.
check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
rm -rf dep
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a
cd vpi ; $(MAKE) clean
cd driver ; $(MAKE) clean
cd ivlpp ; $(MAKE) clean
cd tgt-verilog ; $(MAKE) clean
cd tgt-stub ; $(MAKE) clean
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) clean); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) clean); done
distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) distclean); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) distclean); done
rm -f vvm/Makefile
rm -f vpi/Makefile
rm -f ivlpp/Makefile
rm -f driver/Makefile
rm -f config.status config.cache config.log
rm -f Makefile
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
ifeq (@ENABLE_VVM@,yes)
TT_VVM = t-vvm.o
endif
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_attrib.o \
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o $(TT_VVM) t-xnf.o
FF = nodangle.o synth.o syn-rules.o xnfio.o
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_rconst.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
load_module.o mangle.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_link.o net_modulo.o \
net_proc.o net_scope.o net_udp.o pad_to_width.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 \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o \
$(FF) $(TT)
Makefile: Makefile.in config.h.in config.status
./config.status
libvpi.a: vpithunk.o
rm -f $@
ar cvq $@ vpithunk.o
ranlib $@
# The vpithunk.c file (that makes up the libvpi.a library) needs to
# be make with PIC flags, because shared objects load it.
vpithunk.o: vpithunk.c
@[ -d dep ] || mkdir dep
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
--output-lib libivl.a --output-exp ivl.exp
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR64@;@libdir64@;' \
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
dep:
mkdir dep
%.o: %.cc
@[ -d dep ] || mkdir dep
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
@@ -164,9 +179,9 @@ lexor.o: lexor.cc parse.h
parse.o: parse.cc
parse.cc parse.h: $(srcdir)/parse.y
parse.h parse.cc: $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
mv parse.cc.h parse.h || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
@@ -174,75 +189,41 @@ syn-rules.cc: $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.o: lexor_keyword.cc
lexor_keyword.cc: lexor_keyword.gperf
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
man -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.pdf: iverilog-vpi.ps
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
ifeq (@MING32@,yes)
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
all: dep iverilog-vpi.pdf
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
ifeq (@WIN32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(libdir)/libvpi.a $(WIN32_INSTALL)
cd vpi ; $(MAKE) install
cd ivlpp ; $(MAKE) install
cd driver ; $(MAKE) install
for tgt in $(SUBDIRS) $(SUB_VVM); do (cd $$tgt ; $(MAKE) install); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) install); done
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
$(libdir)/libvpi.a : ./libvpi.a
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl/xnf.conf
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
$(includedir)/_pli_types.h: _pli_types.h
$(INSTALL_DATA) $< $(includedir)/_pli_types.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h $(includedir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@MINGW32@,yes)
ifeq (@WIN32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
@@ -251,31 +232,26 @@ $(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
$(mandir) $(mandir)/man1
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl
uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
for f in xnf.conf xnf-s.conf ivl@EXEEXT@; \
do rm -f $(libdir)/ivl/$$f; done
-rmdir $(libdir)/ivl
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
do rm -f $(bindir)/$$f; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(includedir)/$$f; done
rm -f $(mandir)/man1/iverilog-vpi.1 $(prefix)/iverilog-vpi.pdf
rm -f $(libdir)/ivl/ivl@EXEEXT@
rm -f $(bindir)/verilog
rm -f $(bindir)/gverilog@EXEEXT@
rm -f $(includedir)/ivl_target.h
rm -f $(includedir)/vpi_user.h
cd driver ; $(MAKE) uninstall
cd vpi ; $(MAKE) uninstall
cd ivlpp ; $(MAKE) uninstall
for tgt in $(SUBDIRS) $(SUB_VVM); do (cd $$tgt ; $(MAKE) uninstall); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) uninstall); done
-include $(patsubst %.o, dep/%.d, $O)
+27 -62
View File
@@ -16,8 +16,8 @@
* 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: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
@@ -27,16 +27,17 @@
# include "PWire.h"
# include <assert.h>
/* n is a permallocated string. */
Module::Module(perm_string n)
: name_(n)
Module::Module(const char*name, const svector<Module::port_t*>*pp)
: name_(strdup(name))
{
library_flag = false;
default_nettype = NetNet::NONE;
if (pp)
ports_ = *pp;
}
Module::~Module()
{
free(name_);
}
void Module::add_gate(PGate*gate)
@@ -44,12 +45,12 @@ void Module::add_gate(PGate*gate)
gates_.push_back(gate);
}
void Module::add_task(perm_string name, PTask*task)
void Module::add_task(const string&name, PTask*task)
{
tasks_[name] = task;
}
void Module::add_function(perm_string name, PFunction *func)
void Module::add_function(const string &name, PFunction *func)
{
funcs_[name] = func;
}
@@ -71,56 +72,46 @@ void Module::add_behavior(PProcess*b)
unsigned Module::port_count() const
{
return ports.count();
return ports_.count();
}
/*
* Return the array of PEIdent object that are at this port of the
* module. If the port is internally unconnected, return an empty
* array.
* array.
*/
const svector<PEIdent*>& Module::get_port(unsigned idx) const
{
assert(idx < ports.count());
assert(idx < ports_.count());
static svector<PEIdent*> zero;
if (ports[idx])
return ports[idx]->expr;
if (ports_[idx])
return ports_[idx]->expr;
else
return zero;
}
unsigned Module::find_port(const char*name) const
unsigned Module::find_port(const string&name) const
{
assert(name != "");
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
if (ports[idx] == 0) {
/* It is possible to have undeclared ports. These
are ports that are skipped in the declaration,
for example like so: module foo(x ,, y); The
port between x and y is unnamed and thus
inaccessible to binding by name. */
continue;
}
assert(ports[idx]);
if (ports[idx]->name == name)
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
if (ports_[idx]->name == name)
return idx;
}
return ports.count();
return ports_.count();
}
PWire* Module::get_wire(const pform_name_t&name) const
PWire* Module::get_wire(const hname_t&name) const
{
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
return (*obj).second;
}
PGate* Module::get_gate(perm_string name)
PGate* Module::get_gate(const string&name)
{
for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end()
@@ -133,6 +124,11 @@ 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_;
@@ -146,37 +142,6 @@ 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.
*
* Revision 1.25 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.24 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.23 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.22 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.21 2003/04/02 03:00:14 steve
* Cope with empty module ports while binding by name.
*
* Revision 1.20 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.19 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.18 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+113 -77
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -18,25 +18,21 @@
* 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: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
#endif
# include <list>
# include <map>
# include "svector.h"
# include "StringHeap.h"
# include "HName.h"
# include "named.h"
# include "LineInfo.h"
# include "netlist.h"
# include "pform_types.h"
# include <string>
class PEvent;
class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PSpecPath;
class PTask;
class PFunction;
class PWire;
@@ -59,47 +55,26 @@ class Module : public LineInfo {
the port. */
public:
struct port_t {
perm_string name;
string name;
svector<PEIdent*> expr;
};
public:
/* The name passed here is the module name, not the instance
name. This make must be a permallocated string. */
explicit Module(perm_string name);
explicit Module(const char*name, const svector<port_t*>*);
~Module();
/* Initially false. This is set to true if the module has been
declared as a library module. This makes the module
ineligible for being chosen as an implicit root. It has no
other effect. */
bool library_flag;
NetNet::Type default_nettype;
/* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
into this map. */
struct param_expr_t {
PExpr*expr;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
/* specparams are simpler then other params, in that they have
no type information. They are merely constant
expressions. */
map<perm_string,PExpr*>specparams;
map<string,PExpr*>parameters;
map<string,PExpr*>localparams;
/* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<pform_name_t,PExpr*>defparms;
map<hname_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -107,32 +82,16 @@ class Module : public LineInfo {
appear in the instantiated module. Therefore a
list of names in module-order is needed to pass from
a parameter-index to its name. */
list<perm_string> param_names;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports;
list<string> param_names;
/* Keep a table of named events declared in the module. */
map<perm_string,PEvent*>events;
map<perm_string,PExpr*> attributes;
map<string,PEvent*>events;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
/* The module has a list of genvars that may be used in
various generate schemes. */
list<perm_string> genvars;
/* the module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
list<PSpecPath*> specify_paths;
perm_string mod_name() const { return name_; }
const char*mod_name() const { return name_; }
void add_gate(PGate*gate);
@@ -142,37 +101,41 @@ class Module : public LineInfo {
PWire* add_wire(PWire*wire);
void add_behavior(PProcess*behave);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
void add_task(const string&name, PTask*def);
void add_function(const string&name, PFunction*def);
unsigned port_count() const;
const svector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const char*name) const;
unsigned find_port(const string&) const;
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const pform_name_t&name) const;
PGate* get_gate(perm_string name);
PWire* get_wire(const hname_t&name) const;
PGate* get_gate(const string&name);
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
bool elaborate_scope(Design*, NetScope*scope) const;
bool elaborate_sig(Design*, NetScope*scope) const;
private:
perm_string name_;
char* name_;
map<pform_name_t,PWire*> wires_;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports_;
map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;
map<string,PTask*> tasks_;
map<string,PFunction*> funcs_;
private: // Not implemented
Module(const Module&);
@@ -182,23 +145,96 @@ 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.24 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.42 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
* Revision 1.23 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.41 2006/09/23 04:57:19 steve
* Basic support for specify timing.
* Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.40 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
* Revision 1.21 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
* Revision 1.39 2006/03/30 01:49:07 steve
* Fix instance arrays indexed by overridden parameters.
* Revision 1.20 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.19 2000/05/16 04:05:15 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
*
* Revision 1.18 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.17 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.16 2000/03/12 17:09:40 steve
* Support localparam.
*
* Revision 1.15 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.14 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.13 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.12 2000/01/09 05:50:48 steve
* Support named parameter override lists.
*
* Revision 1.11 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.10 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
* Revision 1.9 1999/08/23 16:48:39 steve
* Parameter overrides support from Peter Monta
* AND and XOR support wide expressions.
*
* Revision 1.8 1999/08/04 02:13:02 steve
* Elaborate module ports that are concatenations of
* module signals.
*
* Revision 1.7 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
*
* Revision 1.6 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.5 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
* Revision 1.4 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
* Revision 1.3 1999/02/21 17:01:57 steve
* Add support for module parameters.
*
* Revision 1.2 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.1 1998/11/03 23:28:52 steve
* Introduce verilog to CVS.
*
* Revision 1.38 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*/
#endif
+31 -96
View File
@@ -16,8 +16,8 @@
* 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: PDelays.cc,v 1.15 2006/07/08 21:48:46 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.cc,v 1.8 2001/12/29 20:19:31 steve Exp $"
#endif
# include "config.h"
@@ -62,92 +62,54 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
static unsigned long calculate_val(Design*des, const NetScope*scope,
const PExpr*expr)
{
assert(expr);
unsigned long val;
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
int shift = scope->time_unit() - des->get_precision();
if (verireal*dr = expr->eval_rconst(des, scope)) {
val = dr->as_long(shift);
delete dr;
} else {
verinum*dv = expr->eval_const(des, scope);
if (dv == 0) {
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
des->errors += 1;
return 0;
}
assert(dv);
val = dv->as_ulong();
val = des->scale_to_precision(val, scope);
delete dv;
}
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
verireal fn = tmp->value();
int shift = scope->time_unit() - des->get_precision();
long delay = fn.as_long(shift);
if (delay < 0)
delay = 0;
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
verinum fn = tmp->value();
unsigned long delay =
des->scale_to_precision(fn.as_ulong(), scope);
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
/* Oops, cannot evaluate down to a constant. */
return dex;
}
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
{
if (dynamic_cast<NetESignal*> (expr))
return expr;
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des);
if (sig == 0) {
cerr << expr->get_line() << ": error: Expression " << *expr
<< " is not suitable for delay expression." << endl;
return 0;
}
expr = new NetESignal(sig);
return expr;
return val;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag) const
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
assert(scope);
int shift = scope->time_unit() - des->get_precision();
if (delay_[0]) {
rise_time = calculate_val(des, scope, delay_[0]);
if (as_nets_flag)
rise_time = make_delay_nets(des, rise_time);
if (delay_[1]) {
fall_time = calculate_val(des, scope, delay_[1]);
if (as_nets_flag)
fall_time = make_delay_nets(des, fall_time);
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, decay_time);
} else {
if (rise_time < fall_time)
@@ -169,33 +131,6 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
/*
* $Log: PDelays.cc,v $
* Revision 1.15 2006/07/08 21:48:46 steve
* Handle real valued literals in net contexts.
*
* Revision 1.14 2006/06/02 04:48:49 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.13 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.12 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.11 2003/06/21 01:21:42 steve
* Harmless fixup of warnings.
*
* Revision 1.10 2003/02/08 19:49:21 steve
* Calculate delay statement delays using elaborated
* expressions instead of pre-elaborated expression
* trees.
*
* Remove the eval_pexpr methods from PExpr.
*
* Revision 1.9 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.8 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
+10 -25
View File
@@ -1,7 +1,7 @@
#ifndef __PDelays_H
#define __PDelays_H
/*
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
* Copyright (c) 1999 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
@@ -18,23 +18,21 @@
* 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: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.h,v 1.5 2001/12/29 20:19:31 steve Exp $"
#endif
# include "svector.h"
# include <string>
# include <iostream>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#endif
class Design;
class NetScope;
class NetExpr;
class PExpr;
/*
@@ -54,10 +52,9 @@ class PDelays {
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag =false) const;
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
void dump_delays(ostream&out) const;
@@ -74,18 +71,6 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.9 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.8 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
+5 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004 Stephen Williams ([email protected])
* Copyright (c) 200Stephen 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
@@ -16,15 +16,15 @@
* 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: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PEvent.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "PEvent.h"
PEvent::PEvent(perm_string n)
PEvent::PEvent(const string&n)
: name_(n)
{
}
@@ -33,25 +33,13 @@ PEvent::~PEvent()
{
}
perm_string PEvent::name() const
string PEvent::name() const
{
return name_;
}
/*
* $Log: PEvent.cc,v $
* Revision 1.5 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+7 -25
View File
@@ -1,7 +1,7 @@
#ifndef __PEvent_H
#define __PEvent_H
/*
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
* Copyright (c) 2000 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
@@ -18,12 +18,11 @@
* 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: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <string>
class Design;
@@ -32,22 +31,20 @@ class NetScope;
/*
* The PEvent class represents event objects. These are things that
* are declared in Verilog as ``event foo;'' The name passed to the
* constructor is the "foo" part of the declaration.
* constructure is the "foo" part of the declaration.
*/
class PEvent : public LineInfo {
public:
// The name is a perm-allocated string. It is the simple name
// of the event, without any scope.
explicit PEvent(perm_string name);
explicit PEvent(const string&name);
~PEvent();
perm_string name() const;
string name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
private:
perm_string name_;
string name_;
private: // not implemented
PEvent(const PEvent&);
@@ -56,21 +53,6 @@ class PEvent : public LineInfo {
/*
* $Log: PEvent.h,v $
* Revision 1.9 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.8 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.7 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+18 -93
View File
@@ -16,8 +16,8 @@
* 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: PExpr.cc,v 1.39 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.29 2001/12/30 21:32:03 steve Exp $"
#endif
# include "config.h"
@@ -46,21 +46,13 @@ bool PExpr::is_constant(Module*) const
return false;
}
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
{
cerr << get_line() << ": error: "
<< "expression not valid as argument to inout port: "
<< *this << endl;
return 0;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
@@ -75,44 +67,13 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod);
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBComp::~PEBComp()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
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))
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
{
}
@@ -178,40 +139,35 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const pform_name_t&that)
: path_(that)
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), idx_(0)
{
}
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
* An identifier can be in a constant expresion 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;
/* */
perm_string tmp = path_.back().name;
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
{ map<string,PExpr*>::const_iterator cur;
cur = mod->parameters.find(path_.peek_name(0));
if (cur != mod->parameters.end()) return true;
}
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->localparams.find(tmp);
{ map<string,PExpr*>::const_iterator cur;
cur = mod->localparams.find(path_.peek_name(0));
if (cur != mod->localparams.end()) return true;
}
@@ -300,37 +256,6 @@ 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.
*
* Revision 1.37 2005/10/04 04:09:25 steve
* Add support for indexed select attached to parameters.
*
* Revision 1.36 2005/08/06 17:58:16 steve
* Implement bi-directional part selects.
*
* Revision 1.35 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.33 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.32 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.31 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.30 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
+141 -450
View File
@@ -18,16 +18,15 @@
* 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: PExpr.h,v 1.90 2007/06/04 19:14:06 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.54 2001/12/30 21:32:03 steve Exp $"
#endif
# include <string>
# include <vector>
# include "netlist.h"
# include "verinum.h"
# include "verireal.h"
# include "LineInfo.h"
# include "pform_types.h"
class Design;
class Module;
@@ -52,38 +51,8 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// This method tests the width that the expression wants to
// be. It is used by elaboration of assignments to figure out
// the width of the expression.
//
// The "min" is the width of the local context, so it the
// minimum width that this function should return. Initially
// this is the same as the lval width.
//
// The "lval" is the width of the destination where this
// result is going to go. This can be used to constrain the
// amount that an expression can reasonably expand. For
// example, there is no point expanding an addition to beyond
// the lval. This extra bit of information allows the
// expression to optimize itself a bit. If the lval==0, then
// the subexpression should not make l-value related
// optimizations.
//
// The unsigned_flag is set to true if the expression is
// unsized and therefore expandable. This happens if a
// sub-expression is an unsized literal. Some expressions make
// special use of that.
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
// Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the
// l-value width of an assignment) or -1 if the expression is
// self-determinted. The sys_task_arg flag is true if
// expressions are allowed to be incomplete.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
// Procedural elaboration of the expression.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
@@ -95,37 +64,34 @@ class PExpr : public LineInfo {
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as NetNet objects. It
// only allows regs suitable for procedural continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is
// useful for arguments to inout ports of module instances and
// ports of tran primitives.
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method. If the
// is_force flag is true, then the set of valid l-value types
// is slightly modified to accomodate the Verilog force
// statement
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
// assignments can be elaborated with this method.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// 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(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
// This attempts to evaluate a constant expression as a
// decimal floating point. This is used when calculating delay
// constants.
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
@@ -135,7 +101,7 @@ class PExpr : public LineInfo {
// Return true if this expression is a valid constant
// expression. the Module pointer is needed to find parameter
// identifiers and any other module specific interpretations
// of expressions.
// of expresions.
virtual bool is_constant(Module*) const;
private: // not implemented
@@ -151,31 +117,25 @@ class PEConcat : public PExpr {
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
// Concatenated Regs can be on the left of procedural
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual bool is_constant(Module*) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
PExpr*repeat_;
@@ -200,7 +160,7 @@ class PEEvent : public PExpr {
edge_t type() const;
PExpr* expr() const;
virtual void dump(ostream&) const;
private:
@@ -222,23 +182,17 @@ 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(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
/* This method returns the full floating point value. */
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual void dump(ostream&) const;
private:
@@ -248,41 +202,30 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string);
explicit PEIdent(const pform_name_t&);
explicit PEIdent(const hname_t&s);
~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,
bool&unsized_flag) const;
// Regs can be on the left of procedural continuous assignments
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
@@ -290,87 +233,28 @@ class PEIdent : public PExpr {
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(Design*des, NetScope*sc) const;
verinum* eval_const(const Design*des, const NetScope*sc) const;
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
const pform_name_t& path() const { return path_; }
const hname_t& path() const;
private:
pform_name_t path_;
private:
// Common functions to calculate parts of part/bit selects.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
private:
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
private:
NetExpr*elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_word_(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_part_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
hname_t path_;
public:
// Use these to support bit- and part-select operators.
PExpr*msb_;
PExpr*lsb_;
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sig,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
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;
// If this is a reference to a memory, this is the index
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
};
class PENumber : public PExpr {
@@ -382,25 +266,17 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -424,22 +300,15 @@ class PEString : public PExpr {
string value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(Design*, NetScope*) const;
virtual bool is_constant(Module*) const;
@@ -454,18 +323,16 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -483,100 +350,65 @@ class PEBinary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
protected:
private:
char op_;
PExpr*left_;
PExpr*right_;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
private:
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
};
/*
* Here are a few specilized classes for handling specific binary
* operators.
*/
class PEBComp : public PEBinary {
public:
explicit PEBComp(char op, PExpr*l, PExpr*r);
~PEBComp();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&flag) const;
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
};
class PEBShift : public PEBinary {
public:
explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval, bool&flag) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
};
/*
@@ -592,21 +424,16 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
private:
PExpr*expr_;
@@ -616,183 +443,26 @@ class PETernary : public PExpr {
/*
* This class represents a parsed call to a function, including calls
* to system functions. The parameters in the parms list are the
* expressions that are passed as input to the ports of the function.
* to system functions.
*/
class PECallFunction : public PExpr {
public:
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);
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool sys_task_arg) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
private:
pform_name_t path_;
hname_t path_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
};
/*
* $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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.86 2006/11/10 04:54:26 steve
* Add test_width methods for PETernary and PEString.
*
* Revision 1.85 2006/11/04 06:19:24 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
* contain unsized numbers.
*
* Revision 1.84 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
* Revision 1.83 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.82 2006/06/02 04:48:49 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.81 2006/04/28 04:28:35 steve
* Allow concatenations as arguments to inout ports.
*
* Revision 1.80 2006/04/16 00:54:04 steve
* Cleanup lval part select handling.
*
* Revision 1.79 2006/04/16 00:15:43 steve
* Fix part selects in l-values.
*
* Revision 1.78 2006/03/25 02:36:26 steve
* Get rid of excess PESTring:: prefix within class declaration.
*
* Revision 1.77 2006/02/02 02:43:57 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.76 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.75 2005/12/07 04:04:23 steve
* Allow constant concat expressions.
*
* Revision 1.74 2005/11/27 17:01:56 steve
* Fix for stubborn compiler.
*
* Revision 1.73 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.72 2005/11/10 13:28:11 steve
* Reorganize signal part select handling, and add support for
* indexed part selects.
*
* Expand expression constant propagation to eliminate extra
* sums in certain cases.
*
* Revision 1.71 2005/10/04 04:09:25 steve
* Add support for indexed select attached to parameters.
*
* Revision 1.70 2005/08/06 17:58:16 steve
* Implement bi-directional part selects.
*
* Revision 1.69 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.68 2005/01/09 20:16:00 steve
* Use PartSelect/PV and VP to handle part selects through ports.
*
* Revision 1.67 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
*
* Revision 1.66 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.65 2003/02/08 19:49:21 steve
* Calculate delay statement delays using elaborated
* expressions instead of pre-elaborated expression
* trees.
*
* Remove the eval_pexpr methods from PExpr.
*
* Revision 1.64 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.63 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.62 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.61 2002/06/04 05:38:43 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.60 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.59 2002/04/23 03:53:59 steve
* Add support for non-constant bit select.
*
* Revision 1.58 2002/04/14 03:55:25 steve
* Precalculate unary - if possible.
*
* Revision 1.57 2002/04/13 02:33:17 steve
* Detect missing indices to memories (PR#421)
*
* Revision 1.56 2002/03/09 04:02:26 steve
* Constant expressions are not l-values for task ports.
*
* Revision 1.55 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.54 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
@@ -808,5 +478,26 @@ class PECallFunction : public PExpr {
*
* Revision 1.50 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.49 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.48 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.47 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.46 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.45 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
* Revision 1.44 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*/
#endif
+7 -15
View File
@@ -16,18 +16,17 @@
* 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: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
#include "PTask.h"
PFunction::PFunction(perm_string name)
: name_(name), ports_(0), statement_(0)
PFunction::PFunction()
: out_(0), ports_(0), statement_(0)
{
return_type_.type = PTF_NONE;
}
PFunction::~PFunction()
@@ -47,21 +46,14 @@ void PFunction::set_statement(Statement*s)
statement_ = s;
}
void PFunction::set_return(PTaskFuncArg t)
void PFunction::set_output(PWire*o)
{
return_type_ = t;
assert(out_ == 0);
out_ = o;
}
/*
* $Log: PFunction.cc,v $
* Revision 1.7 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+17 -88
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2004 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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
@@ -16,8 +16,8 @@
* 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: PGate.cc,v 1.18 2006/01/03 05:22:14 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.cc,v 1.13 2001/11/22 06:20:59 steve Exp $"
#endif
# include "config.h"
@@ -27,7 +27,7 @@
# include "verinum.h"
# include <assert.h>
PGate::PGate(perm_string name,
PGate::PGate(const string&name,
svector<PExpr*>*pins,
const svector<PExpr*>*del)
: name_(name), pins_(pins)
@@ -37,7 +37,7 @@ PGate::PGate(perm_string name,
str1_ = STRONG;
}
PGate::PGate(perm_string name,
PGate::PGate(const string&name,
svector<PExpr*>*pins,
PExpr*del)
: name_(name), pins_(pins)
@@ -47,7 +47,7 @@ PGate::PGate(perm_string name,
str1_ = STRONG;
}
PGate::PGate(perm_string name, svector<PExpr*>*pins)
PGate::PGate(const string&name, svector<PExpr*>*pins)
: name_(name), pins_(pins)
{
str0_ = STRONG;
@@ -90,79 +90,22 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* parameters. This method understands how to handle the different
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
bool as_net_flag) const
{
delay_.eval_delays(des, scope,
rise_expr, fall_expr, decay_expr,
as_net_flag);
}
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
NetExpr*rise_expr, *fall_expr, *decay_expr;
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (rise_expr == 0) {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
rise_time = tmp->value().as_ulong();
} else {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
rise_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
fall_time = tmp->value().as_ulong();
} else {
if (fall_expr != rise_expr) {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
}
des->errors += 1;
fall_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
decay_time = tmp->value().as_ulong();
} else {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
decay_time = 0;
}
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
}
PGAssign::PGAssign(svector<PExpr*>*pins)
: PGate(perm_string(), pins)
: PGate("", pins)
{
assert(pins->count() == 2);
}
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
: PGate(perm_string(), pins, dels)
: PGate("", pins, dels)
{
assert(pins->count() == 2);
}
@@ -171,14 +114,14 @@ PGAssign::~PGAssign()
{
}
PGBuiltin::PGBuiltin(Type t, perm_string name,
PGBuiltin::PGBuiltin(Type t, const string&name,
svector<PExpr*>*pins,
svector<PExpr*>*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{
}
PGBuiltin::PGBuiltin(Type t, perm_string name,
PGBuiltin::PGBuiltin(Type t, const string&name,
svector<PExpr*>*pins,
PExpr*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
@@ -199,23 +142,24 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
: PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = type;
type_ = strdup(type);
}
PGModule::PGModule(perm_string type, perm_string name,
PGModule::PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = type;
type_ = strdup(type);
}
PGModule::~PGModule()
{
free(type_);
}
void PGModule::set_parameters(svector<PExpr*>*o)
@@ -241,28 +185,13 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
perm_string PGModule::get_type()
const char* PGModule::get_type()
{
return type_;
}
/*
* $Log: PGate.cc,v $
* Revision 1.18 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.17 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.16 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.15 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
+21 -73
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -18,12 +18,11 @@
* 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: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $"
#endif
# include "svector.h"
# include "StringHeap.h"
# include "named.h"
# include "LineInfo.h"
# include "PDelays.h"
@@ -50,39 +49,27 @@ class Module;
* strength of the 1 drive.
*/
class PGate : public LineInfo {
public:
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
explicit PGate(perm_string name, svector<PExpr*>*pins,
explicit PGate(const string&name, svector<PExpr*>*pins,
const svector<PExpr*>*del);
explicit PGate(perm_string name, svector<PExpr*>*pins,
explicit PGate(const string&name, svector<PExpr*>*pins,
PExpr*del);
explicit PGate(perm_string name, svector<PExpr*>*pins);
explicit PGate(const string&name, svector<PExpr*>*pins);
virtual ~PGate();
perm_string get_name() const { return name_; }
const string& get_name() const { return name_; }
// This method evaluates the delays all the way to an
// integer. If the delay is non-constant, then set the times
// to 0, print an error message and mark an error to the
// design.
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_net_flag =false) const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
@@ -92,21 +79,21 @@ class PGate : public LineInfo {
void strength0(strength_t);
void strength1(strength_t);
map<perm_string,PExpr*> attributes;
map<string,string> attributes;
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected:
const svector<PExpr*>& get_pins() const { return *pins_; }
const svector<PExpr*>* get_pins() const { return pins_; }
void dump_pins(ostream&out) const;
void dump_delays(ostream&out) const;
private:
perm_string name_;
const string name_;
PDelays delay_;
svector<PExpr*>*pins_;
@@ -128,7 +115,7 @@ class PGAssign : public PGate {
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
~PGAssign();
void dump(ostream&out, unsigned ind =4) const;
void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const;
private:
@@ -154,10 +141,10 @@ class PGBuiltin : public PGate {
TRANIF1, RTRANIF0, RTRANIF1 };
public:
explicit PGBuiltin(Type t, perm_string name,
explicit PGBuiltin(Type t, const string&name,
svector<PExpr*>*pins,
svector<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name,
explicit PGBuiltin(Type t, const string&name,
svector<PExpr*>*pins,
PExpr*del);
~PGBuiltin();
@@ -165,7 +152,7 @@ class PGBuiltin : public PGate {
Type type() const { return type_; }
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const;
private:
@@ -184,16 +171,14 @@ class PGBuiltin : public PGate {
class PGModule : public PGate {
public:
// The name is the *instance* name of the gate.
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(perm_string type, perm_string name,
explicit PGModule(const char*type, const string&name,
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
explicit PGModule(perm_string type, perm_string name,
explicit PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins);
@@ -208,17 +193,15 @@ class PGModule : public PGate {
// method to pass the range to the pform.
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// This returns the module name of this module. It is a
// permallocated string.
perm_string get_type();
const char* get_type();
private:
perm_string type_;
char* type_;
svector<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -239,41 +222,6 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.32 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.31 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.30 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.28 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.27 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.26 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.25 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.24 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.23 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.22 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
-63
View File
@@ -1,63 +0,0 @@
/*
* Copyright (c) 2006 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
* 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: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "PGenerate.h"
# include "PWire.h"
PGenerate::PGenerate(unsigned id)
: id_number(id)
{
parent = 0;
}
PGenerate::~PGenerate()
{
}
PWire* PGenerate::add_wire(PWire*wire)
{
PWire*&ep = wires[wire->path()];
if (ep) return ep;
assert(ep == 0);
ep = wire;
return wire;
}
PWire* PGenerate::get_wire(const pform_name_t&name) const
{
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
if (obj == wires.end())
return 0;
else
return (*obj).second;
}
void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
void PGenerate::add_behavior(PProcess*proc)
{
behaviors.push_back(proc);
}
-100
View File
@@ -1,100 +0,0 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006 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
* 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: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include "HName.h"
# include <list>
# include <map>
# include "pform_types.h"
class Design;
class NetScope;
class PExpr;
class PProcess;
class PGate;
class PWire;
/*
* This represents a generate scheme.
*/
class PGenerate : public LineInfo {
public:
PGenerate(unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
// implicit.
const unsigned id_number;
perm_string scope_name;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT};
scheme_t scheme_type;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
perm_string loop_index;
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
map<pform_name_t,PWire*>wires;
PWire* add_wire(PWire*);
PWire* get_wire(const pform_name_t&name) const;
list<PGate*> gates;
void add_gate(PGate*);
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.
bool generate_scope(Design*des, NetScope*container);
bool elaborate_sig(Design*des) const;
bool elaborate(Design*des) const;
void dump(ostream&out, unsigned indent) const;
private:
bool generate_scope_loop_(Design*des, NetScope*container);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/*
* Copyright (c) 2006 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
* 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: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
#endif
# include "PSpec.h"
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt)
: conditional(false), condition(0), edge(0),
src(src_cnt), dst(dst_cnt),
data_source_expression(0)
{
}
PSpecPath::~PSpecPath()
{
}
-79
View File
@@ -1,79 +0,0 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006 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
* 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: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <vector>
class PExpr;
/*
* The PSpecPath is the parse of a specify path, which is in its most
* general form <path> = <delays>. The <delays> are collected into the
* "delays" vector in all cases, and the variety is in the other
* members.
*
* All paths also have a list of source names in the src vector, and a
* list of destination names in the dst vector. These pairs are the
* actual paths.
*
* If the path is a simple path, then:
* condition == nil
* edge == 0
* data_source_expression == nil
*
* If the path is conditional, then conditional == true and condition
* is the condition expression. If the condition expression is nil,
* then this is an ifnone conditional path.
*
* If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0.
*/
class PSpecPath : public LineInfo {
public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
~PSpecPath();
void elaborate(class Design*des, class NetScope*scope) const;
void dump(std::ostream&out, unsigned ind) const;
public:
// Condition expression, if present.
bool conditional;
class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge;
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
std::vector<perm_string> dst;
// Data source expression
class PExpr* data_source_expression;
std::vector<class PExpr*>delays;
};
#endif
+2 -5
View File
@@ -16,8 +16,8 @@
* 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: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
@@ -48,9 +48,6 @@ void PTask::set_statement(Statement*s)
/*
* $Log: PTask.cc,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+5 -36
View File
@@ -18,34 +18,17 @@
* 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: PTask.h,v 1.14 2007/03/06 05:22:49 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.h,v 1.11 2001/11/22 06:20:59 steve Exp $"
#endif
# include "LineInfo.h"
# include "svector.h"
# include "StringHeap.h"
# include <string>
class Design;
class NetScope;
class PWire;
class Statement;
class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_REG_S,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME
};
struct PTaskFuncArg {
PTaskFuncEnum type;
svector<PExpr*>*range;
};
/*
* The PTask holds the parsed definitions of a task.
@@ -86,18 +69,16 @@ class PTask : public LineInfo {
* The function is similar to a task (in this context) but there is a
* single output port and a set of input ports. The output port is the
* function return value.
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public LineInfo {
public:
explicit PFunction(perm_string name);
explicit PFunction();
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_return(PTaskFuncArg t);
void set_output(PWire*);
void elaborate_scope(Design*des, NetScope*scope) const;
@@ -110,25 +91,13 @@ class PFunction : public LineInfo {
void dump(ostream&, unsigned) const;
private:
perm_string name_;
PTaskFuncArg return_type_;
PWire*out_;
svector<PWire *> *ports_;
Statement *statement_;
};
/*
* $Log: PTask.h,v $
* Revision 1.14 2007/03/06 05:22:49 steve
* Support signed function return values.
*
* Revision 1.13 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.12 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.11 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright (c) 2003-2004 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
* 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: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
PUdp::PUdp(perm_string n, unsigned nports)
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
{
}
unsigned PUdp::find_port(const char*name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
if (ports[idx] == name)
return idx;
}
return ports.count();
}
/*
* $Log: PUdp.cc,v $
* Revision 1.3 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.1 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
*/
+14 -38
View File
@@ -1,7 +1,7 @@
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -18,22 +18,25 @@
* 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: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $"
#endif
# include <map>
# include "StringHeap.h"
# include "svector.h"
# include <string>
# include "verinum.h"
class PExpr;
svector<string>::svector<string>(unsigned size)
: nitems_(size), items_(new string[size])
{
}
/*
* This class represents a parsed UDP. This is a much simpler object
* then a module or macromodule.
*
* - all ports are scalar,
* - all ports are scaler,
* - pin 0 (the first port) is always output,
* and the remaining pins are input.
*
@@ -48,16 +51,15 @@ class PExpr;
* the current output.
*
* If the UDP is sequential, the "initial" member is taken to be the
* initial value assigned in the source, or 'x' if none is given.
* intial value assigned in the source, or 'x' if none is given.
*/
class PUdp {
public:
explicit PUdp(perm_string n, unsigned nports);
explicit PUdp(const string&n, unsigned nports)
: ports(nports), sequential(false), initial(verinum::Vx), name_(n) { }
svector<string>ports;
unsigned find_port(const char*name);
bool sequential;
svector<string>tinput;
@@ -66,11 +68,11 @@ class PUdp {
verinum::V initial;
map<string,PExpr*> attributes;
map<string,string> attributes;
void dump(ostream&out) const;
perm_string name_;
const string name_;
private:
private: // Not implemented
@@ -80,32 +82,6 @@ class PUdp {
/*
* $Log: PUdp.h,v $
* Revision 1.12 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.10 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
* Revision 1.9 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.8 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
+13 -60
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
* Copyright (c) 1999 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
@@ -16,27 +16,23 @@
* 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: PWire.cc,v 1.14 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.cc,v 1.8 2002/01/26 05:28:28 steve Exp $"
#endif
# include "config.h"
# include "PWire.h"
# include <assert.h>
PWire::PWire(const pform_name_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)
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
{
}
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
NetNet::Type PWire::get_wire_type() const
@@ -44,7 +40,7 @@ NetNet::Type PWire::get_wire_type() const
return type_;
}
const pform_name_t& PWire::path() const
const hname_t& PWire::path() const
{
return hname_;
}
@@ -61,10 +57,6 @@ bool PWire::set_wire_type(NetNet::Type t)
if (t == NetNet::REG) { type_ = t; return true; }
return false;
case NetNet::REG:
if (t == NetNet::INTEGER) {
isint_ = true;
return true;
}
if (t == NetNet::REG) return true;
return false;
default:
@@ -101,19 +93,6 @@ bool PWire::set_port_type(NetNet::PortType pt)
}
}
bool PWire::set_data_type(ivl_variable_type_t dt)
{
if (data_type_ != IVL_VT_NO_TYPE)
if (data_type_ != dt)
return false;
else
return true;
assert(data_type_ == IVL_VT_NO_TYPE);
data_type_ = dt;
return true;
}
void PWire::set_signed(bool flag)
{
signed_ = flag;
@@ -124,11 +103,6 @@ bool PWire::get_signed() const
return signed_;
}
bool PWire::get_isint() const
{
return isint_;
}
void PWire::set_range(PExpr*m, PExpr*l)
{
msb_ = svector<PExpr*>(msb_,m);
@@ -139,34 +113,13 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
{
assert(lidx_ == 0);
assert(ridx_ == 0);
assert(type_ == NetNet::REG);
lidx_ = ldx;
ridx_ = 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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.11 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.10 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.9 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.8 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
+50 -61
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -18,15 +18,14 @@
* 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: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
# include <map>
# include "svector.h"
# include "StringHeap.h"
#ifdef HAVE_IOSFWD
# include <iosfwd>
@@ -39,25 +38,23 @@ class Design;
/*
* Wires include nets, registers and ports. A net or register becomes
* a port by declaration, so ports are not separate. The module
* a port by declaration, so ports are not seperate. The module
* identifies a port by keeping it in its port list.
*
* The hname parameter to the constructor is a hierarchical name. It
* 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.
* 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.
*/
class PWire : public LineInfo {
public:
PWire(const pform_name_t&hname,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
// Return a hierarchical name.
const pform_name_t&path() const;
//const string name() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -67,29 +64,23 @@ class PWire : public LineInfo {
void set_signed(bool flag);
bool get_signed() const;
bool get_isint() const;
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
map<perm_string,PExpr*> attributes;
map<string,string> attributes;
// Write myself to the specified stream.
void dump(ostream&out, unsigned ind=4) const;
void dump(ostream&out) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const;
void elaborate_sig(Design*, NetScope*scope) const;
private:
pform_name_t hname_;
hname_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
ivl_variable_type_t data_type_;
bool signed_;
bool isint_; // original type of integer
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide.
@@ -108,48 +99,46 @@ 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.
*
* Revision 1.18 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.17 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.16 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.15 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.12 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.11 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* 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
+3 -3
View File
@@ -16,8 +16,8 @@ execute even the most trivial design. For the purposes of simulation,
we use as our example *the* most trivial simulation:
module main;
initial
initial
begin
$display("Hello, World");
$finish ;
@@ -79,5 +79,5 @@ Verilog packages from the main Debian software site.
* Install From Source
In this case, see README.txt and other documentation that comes with
In this case, see the readme and other documentation that comes with
the source.
+212 -216
View File
@@ -1,5 +1,5 @@
THE ICARUS VERILOG COMPILATION SYSTEM
Copyright 2000-2004 Stephen Williams
THE ICARUS VERILOG COMPILATION SYSTEM
September 17, 2000
1.0 What is ICARUS Verilog?
@@ -9,13 +9,14 @@ described in the IEEE-1364 standard. Of course, it's not quite there
yet. It does currently handle a mix of structural and behavioral
constructs. For a view of the current state of Icarus Verilog, see its
home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
tools. These back-end tools currently include a simulator engine
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA
netlist generator. In the future, backends are expected for EDIF/LPM,
structural Verilog, VHDL, etc.
tools. These back-end tools currently include a simulator written in
C++ called VVM, another faster simulator called VVP, an XNF (Xilinx
Netlist Format) generator and an EDIF fpga netlist generator. In the
future, backends are expected for EDIF/LPM, structural Verilog, VHDL,
etc.
For instructions on how to run Icarus Verilog,
see the ``iverilog'' man page.
@@ -39,7 +40,7 @@ on a UNIX-like system:
- GNU Make
The Makefiles use some GNU extensions, so a basic POSIX
make will not work. Linux systems typically come with a
satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD)
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
typically have GNU make as the gmake program.
- ISO C++ Compiler
@@ -59,22 +60,6 @@ on a UNIX-like system:
A version problem with this program is the most common cause
of difficulty. See the Icarus Verilog FAQ.
- readline 4.2
On Linux systems, this usually means the readline-devel
rpm. In any case, it is the development headers of readline
that are needed.
- termcap
The readline library in turn uses termcap.
If you are building from CVS, you will also need software to generate
the configure scripts.
- autoconf 2.53
This generates configure scripts from configure.in. The 2.53
or later versions are known to work, autoconf 2.13 is
reported to *not* work.
2.2 Compilation
Unpack the tar-ball and cd into the verilog-######### directory
@@ -84,7 +69,7 @@ with the commands:
./configure
make
Normally, this command automatically figures out everything it needs
Normally, this command automatically figures out every thing it needs
to know. It generally works pretty well. There are a few flags to the
configure script that modify its behavior:
@@ -102,28 +87,6 @@ configure script that modify its behavior:
common to use --prefix=/opt. You can configure for a non-root
install with --prefix=$HOME.
--enable-vvp32 (experimental)
If compiling on AMD64 systems, this enables the
compilation of 32bit compatible vvp (vvp32) and the vpi
modules that match.
2.2.1 Special AMD64 Instructions
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
most out of your install, first make sure you have both 64bit and
32bit development libraries installed. Then configure with this
somewhat more complicated command:
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
This reflects the convention on AMD64 systems that 64bit libraries go
into lib64 directories. The "--enable-vvp32" also turns on 32bit
compatibility files. A 32bit version of vvp (vvp32) will be created,
as well as 32bit versions of the development libraries and bundled VPI
libraries.
2.3 (Optional) Testing
To run a simple test before installation, execute
@@ -168,14 +131,14 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
3.2 Parse
The Verilog compiler starts by parsing the Verilog source file. The
output of the parse is a list of Module objects in "pform". The pform
output of the parse in a list of Module objects in PFORM. The pform
(see pform.h) is mostly a direct reflection of the compilation
step. There may be dangling references, and it is not yet clear which
module is the root.
One can see a human readable version of the final pform by using the
One can see a human readable version of the final PFORM by using the
``-P <path>'' flag to the compiler. This will cause iverilog to dump
the pform into the file named <path>.
the PFORM into the file named <path>.
3.3 Elaboration
@@ -190,10 +153,10 @@ The elaborate() function performs the elaboration.
One can see a human readable version of the final, elaborated and
optimized netlist by using the ``-N <path>'' flag to the compiler. If
elaboration succeeds, the final netlist (i.e., after optimizations but
elaboration succeeds, the final netlist (i.e. after optimizations but
before code generation) will be dumped into the file named <path>.
Elaboration is actually performed in two steps: scopes and parameters
Elaboration is actually performed it two steps: scopes and parameters
first, followed by the structural and behavioral elaboration.
3.3.1 Scope Elaboration
@@ -222,19 +185,19 @@ simply passing through the pform.
This is actually a collection of processing steps that perform
optimizations that do not depend on the target technology. Examples of
some useful transformations are
some useful transformations would be,
- eliminate null effect circuitry
- eliminate null effect circuitry,
- combinational reduction
- constant propagation
The actual functions performed are specified on the ivl command line by
the -F flags (see below).
the -F flags (See below).
3.5 Code Generation
This step takes the design netlist and uses it to drive the code
generator (see target.h). This may require transforming the
generator. (See target.h.) This may require transforming the
design to suit the technology.
The emit() method of the Design class performs this step. It runs
@@ -246,9 +209,6 @@ command line.
3.6 ATTRIBUTES
NOTE: The $attribute syntax will soon be deprecated in favor of the
Verilog-2001 attribute syntax, which is cleaner and standardized.
The parser accepts, as an extension to Verilog, the $attribute module
item. The syntax of the $attribute item is:
@@ -277,11 +237,6 @@ between processing steps. Processing steps that are aware of others
may place attributes on netlist objects to communicate information to
later steps.
Icarus Verilog also accepts the Verilog 2001 syntax for
attributes. They have the same general meaning as with the $attribute
syntax, but they are attached to objects by position instead of by
name. Also, the key is a Verilog identifier instead of a string.
4.0 Running iverilog
The preferred way to invoke the compiler is with the iverilog(1)
@@ -289,15 +244,109 @@ command. This program invokes the preprocessor (ivlpp) and the
compiler (ivl) with the proper command line options to get the job
done in a friendly way. See the iverilog(1) man page for usage details.
4.1 Running IVL Directly (not recommended)
4.1 EXAMPLES
NOTE: The preferred method of running Icarus Verilog is the
iverilog command described above. The instructions below may
change at any time without notice.
The ivl command is the compiler driver, that invokes the parser,
optimization functions and the code generator, but not the preprocessor.
Usage: ivl <options>... file
ivl -h
ivl -V
-F <name>
Use this flag to request an optimization function be applied
to the netlist before it is sent to the target output
stage. Any number of -F options may be given, to specify a
variety of processing steps. The steps will be applied in
order, with the output of one uses as the input to the next.
The function is specified by name. Use the "ivl -h" command to
get a list of configured function names.
-h
Print usage information, and exit.
-m <module>
Cause a named VPI module to be included in the module
list. This parameter appends the named module to the end of
the VPI_MODULE_LIST. This is an ordered list of modules to be
loaded into the simulation at runtime.
This list can also be set with -fVPI_MODULE_LIST=<list> which
sets the list completely. Then, -m after this will append
module names to the list specified. The default list
includes "system".
-N <file>
Dump the elaborated netlist to the named file. The netlist is
the folly elaborated netlist, after all the function modules
are applied and right before the output generator is
called. This is an aid for debugging the compiler, and the
output generator in particular.
-o <file>
Normally, the generated result is sent to standard
output. Use the -o flag to specify an output file for the
generated result.
-P <file>
Write the PForm of the parsed input to the specified file.
The pform is the compiler's understanding of the input after
parsing and before elaboration. This is an aid for debugging
the compiler.
-p <assign>
Use this flag to set a parameter value. The format of the
assignment is <key>=<value> where key is any string up to the
first '=', and <value> is the rest of the option. If the '='
is omitted, then the key is assigned the empty string.
The useful keys are defined by the functions and the target in
use. These assignments are specifically useful for passing
target specific information to the target back-end, or
options/parameters to optimization functions, if any are defined.
-s <module>
Normally, ivl will locate all the modules that are defined but
never instantiated, and use these as the design roots for
elaboration. This flag allows the choice of root module(s) to
be manually overridden. It can be used more than once on the
command line if multiple root modules are needed.
-T [min|typ|max]
Normally, ivl will select typ values from min:type:max
expressions and print a warning. This flag tells the compiler
exactly which value to choose, and suppresses the warning.
-t <name>
Select the output format for the compiled result. Use the
"ivl -h" command to get a list of configured targets.
-v Print progress indications, and (if supported by the system)
executions times in ivl precessing steps.
-V
Print version and copyright information for ivl, and exit.
-y <dir>
Add the specified directory to the library search path. If
missing modules are discovered during elaboration, ivl will
attempt to locate an implementation by searching the library
directories for a Verilog source file with the same name as
the module.
4.2 EXAMPLES
Example: Compiling "hello.vl"
------------------------ hello.vl ----------------------------
module main();
initial
initial
begin
$display("Hi there");
$finish ;
@@ -307,7 +356,7 @@ endmodule
--------------------------------------------------------------
Ensure that "iverilog" is on your search path, and the vpi library
Insure that "iverilog" is on your search path, and the vpi library
is available.
To compile the program:
@@ -334,163 +383,110 @@ Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported
constructs.
- System functions are supported, but the return value is a little
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
- block disable not supported, i.e.:
begin : foo
[...]
disable foo; // sorry
[...]
end
- Functions in structural contexts are not supported.
assign foo = user_function(a,b); // sorry
always @(a or b) foo = user_function(a,b); // OK
- real data types not supported. This includes real and
realtime. However, floating point constants in delay expressions
are supported so that `timescale works properly.
- System functions are supported, but the compiler presumes that
they return 32 bits. This is the typical case.
- Specify blocks are parsed but ignored in general.
- trireg is not supported. tri0 and tri1 are supported.
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
and rtranif0 are not supported.
- Net delays, of the form "wire #N foo;" do not work. Delays in
every other context do work properly, including the V2001 form
"wire #5 foo = bar;"
- Event controls inside non-blocking assignments are not supported.
i.e.: a <= @(posedge clk) b;
- Macro arguments are not supported. `define macros are supported,
but they cannot take arguments.
5.1 Nonstandard Constructs or Behaviors
Icarus Verilog includes some features that are not part of the
IEEE1364 standard, but have well defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined. See the "extensions.txt" documentation for
more details.
$is_signed(<expr>)
This system function returns 1 if the expression contained is
signed, or 0 otherwise. This is mostly of use for compiler
regression tests.
$sizeof(<expr>)
$bits(<expr>)
The $bits system function returns the size in bits of the
expression that is its argument. The result of this
function is undefined if the argument doesn't have a
self-determined size.
The $sizeof function is deprecated in favor of $bits, which is
the same thing, but included in the SystemVerilog definition.
$simtime
The $simtime system function returns as a 64bit value the
simulation time, unscaled by the time units of local
scope. This is different from the $time and $stime functions
which return the scaled times. This function is added for
regression testing of the compiler and run time, but can be
used by applications who really want the simulation time.
Note that the simulation time can be confusing if there are
lots of different `timescales within a design. It is not in
general possible to predict what the simulation precision will
turn out to be.
$mti_random()
$mti_dist_uniform
These functions are similar to the IEEE1364 standard $random
functions, but they use the Mersenne Twister (MT19937)
algorithm. This is considered an excellent random number
generator, but does not generate the same sequence as the
standardized $random.
Builtin system functions
Certain of the system functions have well defined meanings, so
can theoretically be evaluated at compile time, instead of
using runtime VPI code. Doing so means that VPI cannot
override the definitions of functions handled in this
manner. On the other hand, this makes them synthesizable, and
also allows for more aggressive constant propagation. The
functions handled in this manner are:
$bits
$signed
$sizeof
$unsigned
Implementations of these system functions in VPI modules will
be ignored.
Preprocessing Library Modules
Icarus Verilog does preprocess modules that are loaded from
libraries via the -y mechanism. However, the only macros
defined during compilation of that file are those that it
defines itself (or includes) or that are defined on the
command line or command file.
Specifically, macros defined in the non-library source files
are not remembered when the library module is loaded. This is
intentional. If it were otherwise, then compilation results
might vary depending on the order that libraries are loaded,
and that is too unpredictable.
It is said that some commercial compilers do allow macro
definitions to span library modules. That's just plain weird.
Width in %t Time Formats
Standard Verilog does not allow width fields in the %t formats
of display strings. For example, this is illegal:
$display("Time is %0t", %time);
Standard Verilog instead relies on the $timeformat to
completely specify the format.
Icarus Verilog allows the programmer to specify the field
width. The "%t" format in Icarus Verilog works exactly as it
does in standard Verilog. However, if the programmer chooses
to specify a minimum width (i.e., "%5t"), then for that display
Icarus Verilog will override the $timeformat minimum width and
use the explicit minimum width.
vpiScope iterator on vpiScope objects.
In the VPI, the normal way to iterate over vpiScope objects
contained within a vpiScope object, is the vpiInternalScope
iterator. Icarus Verilog adds support for the vpiScope
iterator of a vpiScope object, that iterates over *everything*
the is contained in the current scope. This is useful in cases
where one wants to iterate over all the objects in a scope
without iterating over all the contained types explicitly.
time 0 race resolution.
Combinational logic is routinely modeled using always
blocks. However, this can lead to race conditions if the
inputs to the combinational block are initialized in initial
statements. Icarus Verilog slightly modifies time 0 scheduling
by arranging for always statements with ANYEDGE sensitivity
lists to be scheduled before any other threads. This causes
combinational always blocks to be triggered when the values in
the sensitivity list are initialized by initial threads.
Nets with Types
Icarus Verilog support an extension syntax that allows nets
and regs to be explicitly typed. The currently supported types
are logic, bool and real. This implies that "logic" and "bool"
are new keywords. Typical syntax is:
wire real foo = 1.0;
reg logic bar, bat;
... and so forth. The syntax can be turned off by using the
-g2 flag to iverilog, and turned on explicitly with the -g2x
flag to iverilog.
- force to nets are not supported. Force to variables, and
assign/deassign, are supported.
6.0 CREDITS
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
Copyright Stephen Williams. The proper notices are in the head of each
file. However, I have early on received aid in the form of fixes,
Verilog guidance, and especially testing from many people. Testers in
particular include a larger community of people interested in a GPL
Verilog for Linux.
Verilog guidance, and especially testing from many people, including
(in alphabetical order):
Eric Aardoom <[email protected]>
Stephan I. Boettcher <[email protected]>
Ed Carter <[email protected]>
Larry Doolittle <[email protected]>
Guy Hutchison <[email protected]>
Ales Hvezda <[email protected]>
Venkat Iyer <[email protected]>
Yasuhisa Kato <[email protected]>
James Lee <[email protected]>
Peter Monta <[email protected]>
Daniel H. Nelsen <[email protected]>
Stefan Petersen <[email protected]>
Jason Schonberg <[email protected]>
Stuart Sutherland <[email protected]>
Stephen Tell <[email protected]>
Stefan Theide <[email protected]>
Tom Verbeure
Steve Wilson <[email protected]>
and others. Testers in particular include a larger community of people
interested in a GPL Verilog for Linux. Special thanks to Steve Wilson
for collecting and organizing the test suite code for all those testers.
6.1 PORT MAINTAINERS
This is a list of people who have created ports and precompiled
packages for various operating systems. These folks have graciously
taken on the task of building Icarus Verilog on their systems and
bundled it into neat packages.(+) If you want to be added to the list (or
removed from the list) send e-mail to me.
FreeBSD/{Intel,alpha}
Ying-Chieh Liao <[email protected]>
Linux/{alpha,Intel} (RPMS)
Stephen Williams <[email protected]>
Linux/* (.debs)
Hamish Moffatt <[email protected]>
Macintosh -- MacO/S
Yasuhisa Kato <[email protected]>
Mac O/S X
Timothy J. Wood <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
Solaris/SPARC packages (.pkg)
Dan McMahill <[email protected]>
Cygwin32/*
Venkat Iyer <[email protected]>
Mingw32
Venkat Iyer <[email protected]>
(+) These are not the only systems where Icarus Verilog has been run,
just the systems where precompiled binaries are publicly available.
6.2 TEST SUITE MANAGER
Steve Wilson <[email protected]> or <[email protected]> has taken on
the large task of managing the test suite. He has maintained the
regression test scripts, the driver list, received submissions from
myself and others, and has written a great many tests on his own. Any
compiler writer, for any language, will tell you that the test suite
is at least as important as the compiler code itself.
+8 -42
View File
@@ -16,8 +16,8 @@
* 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: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
@@ -32,19 +32,17 @@ Statement::~Statement()
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = de;
if (de) delay_.set_delay(de);
}
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
: event_(ev), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::~PAssign_()
@@ -86,7 +84,7 @@ PAssignNB::~PAssignNB()
{
}
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
: name_(n), bl_type_(t), list_(st)
{
}
@@ -107,22 +105,16 @@ PBlock::~PBlock()
delete list_[idx];
}
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
PCallTask::PCallTask(const hname_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 pform_name_t& PCallTask::path() const
const hname_t& PCallTask::path() const
{
return path_;
}
@@ -184,7 +176,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const pform_name_t&sc)
PDisable::PDisable(const hname_t&sc)
: scope_(sc)
{
}
@@ -196,7 +188,6 @@ PDisable::~PDisable()
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
assert(expr_.count() > 0);
}
@@ -206,11 +197,6 @@ PEventStatement::PEventStatement(PEEvent*ee)
expr_[0] = ee;
}
PEventStatement::PEventStatement(void)
: statement_(0)
{
}
PEventStatement::~PEventStatement()
{
// delete the events and the statement?
@@ -279,7 +265,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const pform_name_t&e)
PTrigger::PTrigger(const hname_t&e)
: event_(e)
{
}
@@ -301,26 +287,6 @@ 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.
*
* Revision 1.28 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.27 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.26 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.25 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+16 -79
View File
@@ -18,13 +18,12 @@
* 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: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $"
#endif
# include <string>
# include "svector.h"
# include "StringHeap.h"
# include "PDelays.h"
# include "PExpr.h"
# include "HName.h"
@@ -36,7 +35,6 @@ class Design;
class NetAssign_;
class NetCAssign;
class NetDeassign;
class NetForce;
class NetScope;
/*
@@ -55,13 +53,9 @@ class PProcess : public LineInfo {
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -103,7 +97,7 @@ class PAssign_ : public Statement {
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
PExpr* delay_;
PDelays delay_;
PEventStatement*event_;
private:
@@ -123,6 +117,8 @@ class PAssign : public PAssign_ {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, NetScope*scope) const;
};
class PAssignNB : public PAssign_ {
@@ -152,7 +148,7 @@ class PBlock : public Statement {
public:
enum BL_TYPE { BL_SEQ, BL_PAR };
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t);
~PBlock();
@@ -165,7 +161,7 @@ class PBlock : public Statement {
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
perm_string name_;
string name_;
const BL_TYPE bl_type_;
svector<Statement*>list_;
};
@@ -173,11 +169,10 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
~PCallTask();
const pform_name_t& path() const;
const hname_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -198,7 +193,7 @@ class PCallTask : public Statement {
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
pform_name_t path_;
hname_t path_;
svector<PExpr*> parms_;
};
@@ -292,19 +287,19 @@ class PDelayStatement : public Statement {
/*
* This represents the parsing of a disable <scope> statement.
* This represends the parsing of a disable <scope> statement.
*/
class PDisable : public Statement {
public:
explicit PDisable(const pform_name_t&sc);
explicit PDisable(const hname_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
pform_name_t scope_;
hname_t scope_;
};
/*
@@ -313,7 +308,6 @@ class PDisable : public Statement {
*
* @name <statement>;
* @(expr) <statement>;
* @* <statement>;
*/
class PEventStatement : public Statement {
@@ -321,8 +315,6 @@ class PEventStatement : public Statement {
explicit PEventStatement(const svector<PEEvent*>&ee);
explicit PEventStatement(PEEvent*ee);
// Make an @* statement.
explicit PEventStatement(void);
~PEventStatement();
@@ -336,8 +328,6 @@ class PEventStatement : public Statement {
// elaborated statement to the event.
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
private:
svector<PEEvent*>expr_;
Statement*statement_;
@@ -349,7 +339,7 @@ class PForce : public Statement {
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -397,7 +387,6 @@ class PNoop : public Statement {
public:
PNoop() { }
~PNoop() { }
};
class PRepeat : public Statement {
@@ -434,14 +423,14 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const pform_name_t&ev);
explicit PTrigger(const hname_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
pform_name_t event_;
hname_t event_;
};
class PWhile : public Statement {
@@ -461,58 +450,6 @@ 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.
*
* Revision 1.42 2005/12/05 21:21:18 steve
* Fixes for stubborn compilers.
*
* Revision 1.41 2004/12/11 02:31:25 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.40 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.39 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.38 2003/05/19 02:50:58 steve
* Implement the wait statement behaviorally instead of as nets.
*
* Revision 1.37 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.36 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.35 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.34 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.33 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.32 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.31 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
-206
View File
@@ -1,206 +0,0 @@
/*
* Copyright (c) 2002-2004 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
* 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: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
#endif
# include "StringHeap.h"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
StringHeap::StringHeap()
{
cell_base_ = 0;
cell_ptr_ = HEAPCELL;
cell_count_ = 0;
}
StringHeap::~StringHeap()
{
// This is a planned memory leak. The string heap is intended
// to hold permanently-allocated strings.
}
const char* StringHeap::add(const char*text)
{
unsigned len = strlen(text);
assert((len+1) <= HEAPCELL);
unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL);
cell_ptr_ = 0;
cell_count_ += 1;
assert(cell_base_ != 0);
}
char*res = cell_base_ + cell_ptr_;
memcpy(res, text, len);
cell_ptr_ += len;
cell_base_[cell_ptr_++] = 0;
assert(cell_ptr_ <= HEAPCELL);
return res;
}
perm_string StringHeap::make(const char*text)
{
return perm_string(add(text));
}
StringHeapLex::StringHeapLex()
{
hit_count_ = 0;
add_count_ = 0;
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1)
hash_table_[idx] = 0;
}
StringHeapLex::~StringHeapLex()
{
}
unsigned StringHeapLex::add_hit_count() const
{
return hit_count_;
}
unsigned StringHeapLex::add_count() const
{
return add_count_;
}
static unsigned hash_string(const char*text)
{
unsigned h = 0;
while (*text) {
h = (h << 4) ^ (h >> 28) ^ *text;
text += 1;
}
return h;
}
const char* StringHeapLex::add(const char*text)
{
unsigned hash_value = hash_string(text) % HASH_SIZE;
/* If we easily find the string in the hash table, then return
that and be done. */
if (hash_table_[hash_value]
&& (strcmp(hash_table_[hash_value], text) == 0)) {
hit_count_ += 1;
return hash_table_[hash_value];
}
/* The existing hash entry is not a match. Replace it with the
newly allocated value, and return the new pointer as the
result to the add. */
const char*res = StringHeap::add(text);
hash_table_[hash_value] = res;
add_count_ += 1;
return res;
}
perm_string StringHeapLex::make(const char*text)
{
return perm_string(add(text));
}
perm_string StringHeapLex::make(const string&text)
{
return perm_string(add(text.c_str()));
}
bool operator == (perm_string a, const char*b)
{
if (a.str() == b)
return true;
if (! (a.str() && b))
return false;
if (strcmp(a.str(), b) == 0)
return true;
return false;
}
bool operator == (perm_string a, perm_string b)
{
return a == b.str();
}
bool operator != (perm_string a, const char*b)
{
return ! (a == b);
}
bool operator != (perm_string a, perm_string b)
{
return ! (a == b);
}
bool operator < (perm_string a, perm_string b)
{
if (b.str() && !a.str())
return true;
if (b.str() == a.str())
return false;
if (strcmp(a.str(), b.str()) < 0)
return true;
return false;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.6 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.5 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.4 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
-147
View File
@@ -1,147 +0,0 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2004 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
* 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: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
#endif
# include "config.h"
# include <string>
using namespace std;
class perm_string {
public:
perm_string() : text_(0) { }
perm_string(const perm_string&that) : text_(that.text_) { }
~perm_string() { }
perm_string& operator = (const perm_string&that)
{ text_ = that.text_; return *this; }
const char*str() const { return text_; }
operator const char* () const { return str(); }
// This is an escape for making perm_string objects out of
// literals. For example, per_string::literal("Label"); Please
// do *not* cheat and pass arbitrary const char* items here.
static perm_string literal(const char*t) { return perm_string(t); }
private:
friend class StringHeap;
friend class StringHeapLex;
perm_string(const char*t) : text_(t) { };
private:
const char*text_;
};
extern bool operator == (perm_string a, perm_string b);
extern bool operator == (perm_string a, const char* b);
extern bool operator != (perm_string a, perm_string b);
extern bool operator != (perm_string a, const char* b);
extern bool operator > (perm_string a, perm_string b);
extern bool operator < (perm_string a, perm_string b);
extern bool operator >= (perm_string a, perm_string b);
extern bool operator <= (perm_string a, perm_string b);
/*
* The string heap is a way to permanently allocate strings
* efficiently. They only take up the space of the string characters
* and the terminating nul, there is no malloc overhead.
*/
class StringHeap {
public:
StringHeap();
~StringHeap();
const char*add(const char*);
perm_string make(const char*);
private:
enum { HEAPCELL = 0x10000 };
char*cell_base_;
unsigned cell_ptr_;
unsigned cell_count_;
private: // not implemented
StringHeap(const StringHeap&);
StringHeap& operator= (const StringHeap&);
};
/*
* A lexical string heap is a string heap that makes an effort to
* return the same pointer for identical strings. This saves further
* space by not allocating duplicate strings, so in a system with lots
* of identifiers, this can theoretically save more space.
*/
class StringHeapLex : private StringHeap {
public:
StringHeapLex();
~StringHeapLex();
const char*add(const char*);
perm_string make(const char*);
perm_string make(const string&);
unsigned add_count() const;
unsigned add_hit_count() const;
private:
enum { HASH_SIZE = 4096 };
const char*hash_table_[HASH_SIZE];
unsigned add_count_;
unsigned hit_count_;
private: // not implemented
StringHeapLex(const StringHeapLex&);
StringHeapLex& operator= (const StringHeapLex&);
};
/*
* $Log: StringHeap.h,v $
* Revision 1.6 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.5 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
#endif
-129
View File
@@ -1,129 +0,0 @@
#ifndef PLI_TYPES
#define PLI_TYPES
/*
* Copyright (c) 2003 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
* 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: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
/*
* If the host environment has the stdint.h header file,
* then use that to size our PLI types.
*/
#ifndef __STDC_FORMAT_MACROS
# define __STDC_FORMAT_MACROS
#endif
# include <inttypes.h>
typedef uint64_t PLI_UINT64;
typedef int64_t PLI_INT64;
typedef uint32_t PLI_UINT32;
typedef int32_t PLI_INT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
# define PLI_UINT64_FMT PRIu64
#else
/*
* If we do not have the c99 stdint.h header file, then use
* configure detection to guess the pli types ourselves.
*/
# define SIZEOF_UNSIGNED_LONG_LONG 8
# define SIZEOF_UNSIGNED_LONG 8
# define SIZEOF_UNSIGNED 4
#if SIZEOF_UNSIGNED >= 8
typedef unsigned PLI_UINT64;
typedef int PLI_INT64;
# define PLI_UINT64_FMT "u"
#else
# if SIZEOF_UNSIGNED_LONG >= 8
typedef unsigned long PLI_UINT64;
typedef long PLI_INT64;
# define PLI_UINT64_FMT "lu"
# else
# if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG
typedef unsigned long long PLI_UINT64;
typedef long long PLI_INT64;
# define PLI_UINT64_FMT "llu"
# else
typedef unsigned long PLI_UINT64;
typedef long PLI_INT64;
# define PLI_UINT64_FMT "lu"
# endif
# endif
#endif
typedef signed int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
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.
*
* Revision 1.6 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*
* Revision 1.5 2003/10/29 03:28:27 steve
* Add the PLU_UINT64_FMT string for formatting output.
*
* Revision 1.4 2003/10/29 03:23:12 steve
* Portably handle time format of VCD prints.
*
* Revision 1.3 2003/10/02 21:30:06 steve
* Use configured TIME_FMT in vcd dump printf.
*
* Revision 1.2 2003/10/02 19:33:44 steve
* Put libraries in libdir64.
*
* Revision 1.1 2003/09/30 01:33:13 steve
* Add PLI_UINT64 to _pli_types.h.
*
* Revision 1.2 2003/05/26 04:39:16 steve
* Typo type name.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/
#endif
-354
View File
@@ -1,354 +0,0 @@
#ifndef __acc_user_H
#define __acc_user_H
/*
* Copyright (c) 2002 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
* 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: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
#endif
/*
* This header file contains the definitions and declarations needed
* by an Icarus Verilog user using acc_ routines.
*
* NOTE: Icarus Verilog does not support acc_ routines. This is just a
* stub. The functions that are implemented here are actually
* implemented using VPI routines.
*/
#ifdef __cplusplus
# define EXTERN_C_START extern "C" {
# define EXTERN_C_END }
#else
# define EXTERN_C_START
# define EXTERN_C_END
# define bool int
#endif
EXTERN_C_START
# include "_pli_types.h"
/*
* This is a declaration of the "handle" type that is compatible with
* the vpiHandle from vpi_user.h. The libveriuser library implements
* the acc handle type as a vpiHandle, to prevent useless indirection.
*/
typedef struct __vpiHandle *handle;
/* OBJECT TYPES */
#define accModule 20
#define accScope 21
#define accNet 25
#define accReg 30
#define accIntegerParam 200
#define accRealParam 202
#define accStringParam 204
#define accParameter 220
#define accTopModule 224
#define accModuleInstance 226
#define accWire 260
#define accNamedEvent 280
#define accIntegerVar 281
#define accRealVar 282
#define accTimeVar 283
#define accIntVar accIntegerVar
#define accScalar 300
#define accVector 302
#define accUnknown 412
#define accConstant 600
/* type VALUES FOR t_setval_delay STRUCTURE */
#define accNoDelay 0
#define accInertialDelay 1
#define accTransportDelay 2
#define accPureTransportDelay 3
#define accForceFlag 4
#define accReleaseFlag 5
/* type VALUES FOR t_setval_value STRUCTURE */
#define accBinStrVal 1
#define accOctStrVal 2
#define accDecStrVal 3
#define accHexStrVal 4
#define accScalarVal 5
#define accIntVal 6
#define accRealVal 7
#define accStringVal 8
#define accVectorVal 9
/* Scalar values */
#define acc0 0
#define acc1 1
#define accX 2
#define accZ 3
/* type VALUES FOR t_acc_time STRUCTURE */
#define accTime 1
#define accSimTime 2
#define accRealTime 3
/* reason codes */
#define logic_value_change 1
#define strength_value_change 2
#define real_value_change 3
#define vector_value_change 4
#define event_value_change 5
#define integer_value_change 6
#define time_value_change 7
#define sregister_value_change 8
#define vregister_value_change 9
#define realtime_value_change 10
/* VCL strength values */
#define vclSupply 7
#define vclStrong 6
#define vclPull 5
#define vclLarge 4
#define vclWeak 3
#define vclMedium 2
#define vclSmall 1
#define vclHighZ 0
/* Constants used by acc_vcl_add */
#define vcl_verilog_logic 2
#define VCL_VERILOG_LOGIC vcl_verilog_logic
#define vcl_verilog_strength 3
#define VCL_VERILOG_STRENGTH vcl_verilog_strength
typedef struct t_acc_time {
int type;
int low, high;
double real;
} s_acc_time, *p_acc_time;
typedef struct t_setval_delay {
s_acc_time time;
int model;
} s_setval_delay, *p_setval_delay;
typedef struct t_acc_vecval {
int aval;
int bval;
} s_acc_vecval, *p_acc_vecval;
typedef struct t_setval_value {
int format;
union {
char*str;
int scalar;
int integer;
double real;
p_acc_vecval vector;
} value;
} s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;
typedef struct t_strengths {
PLI_UBYTE8 logic_value;
PLI_UBYTE8 strength1;
PLI_UBYTE8 strength2;
} s_strengths, *p_strengths;
typedef struct t_vc_record {
PLI_INT32 vc_reason;
PLI_INT32 vc_hightime;
PLI_INT32 vc_lowtime;
void* user_data;
union {
PLI_UBYTE8 logic_value;
double real_value;
handle vector_handle;
s_strengths strengths_s;
} out_value;
} s_vc_record, *p_vc_record;
typedef struct t_location {
PLI_INT32 line_no;
const char*filename;
} s_location, *p_location;
extern int acc_error_flag;
extern int acc_initialize(void);
extern void acc_close(void);
/*
* This is the acc_configure command, and the config_param
* codes that are accepted.
*/
extern int acc_configure(PLI_INT32 config_param, const char*value);
#define accEnableArgs 6
#define accDevelopmentVersion 11
extern int acc_fetch_argc(void);
extern char**acc_fetch_argv(void);
extern PLI_INT32 acc_fetch_direction(handle obj);
/* XXXX FIXME: Values returned by acc_fetch_direction */
# define accInout 2
extern char* acc_fetch_fullname(handle obj);
extern int acc_fetch_location(p_location loc, handle obj);
extern char* acc_fetch_name(handle obj);
extern char* acc_fetch_defname(handle obj);
extern double acc_fetch_paramval(handle obj);
extern double acc_fetch_tfarg(PLI_INT32);
extern double acc_fetch_itfarg(PLI_INT32, handle);
extern PLI_INT32 acc_fetch_tfarg_int(PLI_INT32);
extern PLI_INT32 acc_fetch_itfarg_int(PLI_INT32, handle);
extern char* acc_fetch_tfarg_str(PLI_INT32);
extern char* acc_fetch_itfarg_str(PLI_INT32, handle);
typedef struct t_timescale_info {
PLI_INT16 unit;
PLI_INT16 precision;
} s_timescale_info, *p_timescale_info;
extern void acc_fetch_timescale_info(handle obj, p_timescale_info info);
extern PLI_INT32 acc_fetch_size(handle obj);
extern PLI_INT32 acc_fetch_type(handle obj);
extern PLI_INT32 acc_fetch_fulltype(handle obj);
extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb);
extern char* acc_fetch_type_str(PLI_INT32 type);
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
extern handle acc_handle_by_name(const char*name, handle scope);
extern handle acc_handle_hiconn(handle port_ref_handle);
extern handle acc_handle_object(const char*name);
extern handle acc_handle_parent(handle obj);
extern handle acc_handle_scope(handle obj);
extern handle acc_handle_simulated_net(handle net);
extern handle acc_handle_tfarg(int n);
extern handle acc_handle_tfinst(void);
extern PLI_INT32 acc_compare_handles(handle, handle);
extern handle acc_next(PLI_INT32 *, handle, handle);
extern handle acc_next_bit(handle ref, handle bit);
extern handle acc_next_port(handle ref, handle bit);
extern handle acc_next_scope(handle, handle);
extern handle acc_next_topmod(handle prev_topmod);
extern int acc_object_in_typelist(handle object, PLI_INT32*typelist);
extern int acc_object_of_type(handle object, PLI_INT32 type);
extern char*acc_product_version(void);
extern char*acc_set_scope(handle ref, ...);
extern int acc_set_value(handle obj, p_setval_value value,
p_setval_delay delay);
extern void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
void*data, PLI_INT32 vcl_flag);
extern void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
void*data, PLI_INT32 vcl_flag);
extern char* acc_version(void);
EXTERN_C_END
/*
* $Log: acc_user.h,v $
* Revision 1.20 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.19 2003/10/10 02:57:45 steve
* Some PLI1 stubs.
*
* Revision 1.18 2003/06/13 19:23:41 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.17 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.16 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.15 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.14 2003/05/29 02:21:45 steve
* Implement acc_fetch_defname and its infrastructure in vvp.
*
* Revision 1.13 2003/05/24 03:02:04 steve
* Add implementation of acc_handle_by_name.
*
* Revision 1.12 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
* Add tf_isetdelay and friends, and add
* callback return values for acc_vcl support.
*
* Revision 1.11 2003/04/24 18:57:05 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.10 2003/04/20 02:48:39 steve
* Support value change callbacks.
*
* Revision 1.9 2003/04/12 18:57:13 steve
* More acc_ function stubs.
*
* Revision 1.8 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.7 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
* Revision 1.4 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
* Revision 1.3 2002/06/02 19:03:29 steve
* Add acc_handle_tfarg and acc_next_topmode
*
* Revision 1.2 2002/05/30 02:06:05 steve
* Implement acc_product_version.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
#endif
Vendored
-207
View File
@@ -1,207 +0,0 @@
# AX_CPP_IDENT
# ------------
# Check if the C compiler supports #ident
# Define and substitute ident_support if so.
#
# It would be simpler and more consistent with the rest of the autoconf
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
# change would require all C files in the icarus top level directory to
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
# ident_support handling from the Makefile. Manyana.
#
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.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)])])
if test $ax_cv_cpp_ident = yes; then
ident_support='-DHAVE_CVS_IDENT=1'
fi
AC_SUBST(ident_support)
])# AC_CPP_IDENT
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# ------------------------------
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
# Unwarranted assumptions:
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
# - the nm(1) utility is available, and its name is "nm".
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
[AC_COMPILE_IFELSE([void underscore(void){}],
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])]
)])
# AX_C_UNDERSCORES_LEADING
# ---------------------------------
# Check if symbol names in object files produced by C compiler have
# leading underscores. Define NEED_LU if so.
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
[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], [1], [Symbol names in object files produced by C compiler have leading underscores.])
fi
])# AX_C_UNDERSCORES_LEADING
# AX_C_UNDERSCORES_TRAILING
# ---------------------------------
# Check if symbol names in object files produced by C compiler have
# trailing underscores. Define NEED_TU if so.
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
[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], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
fi
])# AX_C_UNDERSCORES_TRAILING
# AX_WIN32
# --------
# Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with
AC_DEFUN([AX_WIN32],
[AC_CYGWIN
AC_MINGW32
WIN32=no
AC_MSG_CHECKING([for Microsoft Windows])
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
])# AX_WIN32
# AX_LD_EXTRALIBS
# ---------------
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
AC_DEFUN([AX_LD_EXTRALIBS],
[AC_MSG_CHECKING([for extra libs needed])
EXTRALIBS=
case "${host}" in
*-*-cygwin* )
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
])# AX_LD_EXTRALIBS
# AX_LD_SHAREDLIB_OPTS
# --------------------
# linker options when building a shared library
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
[AC_MSG_CHECKING([for shared library link flag])
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
])# AX_LD_SHAREDLIB_OPTS
# AX_C_PICFLAG
# ------------
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
AC_DEFUN([AX_C_PICFLAG],
[AC_MSG_CHECKING([for flag to make position independent code])
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
])# AX_C_PICFLAG
# AX_LD_RDYNAMIC
# --------------
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_DEFUN([AX_LD_RDYNAMIC],
[AC_MSG_CHECKING([for -rdynamic compiler flag])
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-openbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
# since we didn't tell them we're "checking", no good place to tell the answer
# AC_MSG_RESULT($strip_dynamic)
])# AX_LD_RDYNAMIC
# AX_CPP_PRECOMP
# --------------
AC_DEFUN([AX_CPP_PRECOMP],
[# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
])# AX_CPP_PRECOMP
-120
View File
@@ -1,120 +0,0 @@
/*
* Copyright (c) 2002 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
* 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: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
#endif
# include "config.h"
# include "functor.h"
# include "netlist.h"
# include <assert.h>
bool NetAssign::is_asynchronous()
{
return true;
}
bool NetCondit::is_asynchronous()
{
return false;
}
/*
* NetEvWait statements come from statements of the form @(...) in the
* Verilog source. These event waits are considered asynchronous if
* all of the events in the list are ANYEDGE, and all the inputs to
* the statement are included in the sensitivity list. If any of the
* events are posedge or negedge, the statement is synchronous
* (i.e. an edge-triggered flip-flop) and if any of the inputs are
* unaccounted for in the sensitivity list then the statement is a
* latch.
*/
bool NetEvWait::is_asynchronous()
{
/* The "sense" set contains the set of Nexa that are in the
sensitivity list. We also require that the events are all
level sensitive, but the nex_async_ method takes care of
that test. */
NexusSet*sense = new NexusSet;
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
NexusSet*tmp = event(idx)->nex_async_();
if (tmp == 0) {
delete sense;
return false;
}
sense->add(*tmp);
delete tmp;
}
NexusSet*inputs = statement_->nex_input();
if (! sense->contains(*inputs)) {
delete sense;
delete inputs;
return false;
}
delete sense;
delete inputs;
/* If it passes all the other tests, then this statement is
asynchronous. */
return true;
}
bool NetProc::is_asynchronous()
{
return false;
}
bool NetProcTop::is_asynchronous()
{
if (type_ == NetProcTop::KINITIAL)
return false;
return statement_->is_asynchronous();
}
/*
* $Log: async.cc,v $
* Revision 1.7 2004/01/18 23:26:54 steve
* The is_combinational function really need not recurse.
*
* Revision 1.6 2003/12/20 00:33:39 steve
* More thorough check that NetEvWait is asynchronous.
*
* Revision 1.5 2003/09/04 20:28:05 steve
* Support time0 resolution of combinational threads.
*
* Revision 1.4 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/07/04 00:24:16 steve
* initial statements are not asynchronous.
*
* Revision 1.1 2002/06/30 02:21:31 steve
* Add structure for asynchronous logic synthesis.
*
*/
-85
View File
@@ -1,85 +0,0 @@
ATTRIBUTE NAMING CONVENTIONS
Attributes that are specific to Icarus Verilog, and are intended to be
of use to programmers, start with the prefix "ivl_".
Attributes with the "_ivl_" prefix are set aside for internal
use. They may be generated internally by the compiler. They need not
be documented here.
ATTRIBUTES TO CONTROL SYNTHESIS
The following is a summary of Verilog attributes that Icarus Verilog
understands within Verilog source files to control synthesis
behavior. This section documents generic synthesis attributes. For
target specific attributes, see target specific documentation.
These attributes only effect the behavior of the synthesizer. For
example, the ivl_combinational will not generate an error message
if the Verilog is being compiled for simulation. (It may generate a
warning.)
* Attributes for "always" and "initial" statements
(* ivl_combinational *)
This attribute tells the compiler that the statement models
combinational logic. If the compiler finds that it cannot make
combinational logic out of a marked always statement, it will
report an error.
This attribute can be used to prevent accidentally inferring
latches or flip-flops where the user intended combinational
logic.
(* ivl_synthesis_on *)
This attribute tells the compiler that the marked always statement
is synthesizable. The compiler will attempt to synthesize the
code in the marked "always" statement. If it cannot in any way
synthesize it, then it will report an error.
(* ivl_synthesis_off *)
If this value is attached to an "always" statement, then the
compiler will *not* synthesize the "always" statement. This can be
used, for example, to mark embedded test bench code.
* Attributes for modules
(* ivl_synthesis_cell *)
If this value is attached to a module during synthesis, that
module will be considered a target architecture primitive, and
its interior will not be synthesized further. The module can
therefore hold a model for simulation purposes.
* Attributes for signals (wire/reg/integer/tri/etc.)
(* PAD = "<pad assignment list>" *)
If this attribute is attached to a signal that happens to be a
root module port, then targets that support it will use the string
value as a list of pin assignments for the port/signal. The format
is a comma separated list of location tokens, with the format of
the token itself defined by the back-end tools in use.
* Other Attributes
[ none defined yet ]
MISC
(* _ivl_schedule_push *)
If this attribute is attached to a thread object (always or
initial statement) then the vvp code generator will generate code
that causes the scheduler to push this thread at compile time. The
compiler may internally add this attribute to always statements if
it detects that it is combinational. This helps resolve time-0
races.
+3 -3
View File
@@ -7,12 +7,12 @@
# to just run this script to autoconf wherever needed.
#
echo "Autoconf in root..."
autoconf -f
autoconf
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub libveriuser cadpli
for dir in vpip vvp tgt-vvp tgt-fpga
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf -f --include=.. )
( cd $dir ; autoconf )
done
echo "Precompiling lexor_keyword.gperf"
-7
View File
@@ -1,7 +0,0 @@
Makefile
cadpli.vpl
dep
configure
config.log
config.status
autom4te.cache
-104
View File
@@ -1,104 +0,0 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library 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
#
#ident "$Id: Makefile.in,v 1.13 2007/02/06 05:07:31 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
vpidir = @libdir@/ivl/@vpidir1@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
SHARED = @shared@
all:
ifeq (@enable_vvp32@,yes)
vpidir32 = $(libdir)/ivl/@vpidir2@
ALL32 = all32
INSTALL32 = install32
UNINSTALL32 = uninstall32
include $(srcdir)/enable_vvp32.mk
endif
all: dep cadpli.vpl $(ALL32)
# No specific check operations.
check: all
dep:
mkdir dep
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
mv $*.d dep
O = cadpli.o
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MING32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
endif
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
clean:
rm -rf *.o dep cadpli.vpl bin32
distclean: clean
rm -f Makefile config.status config.log config.cache
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(vpidir)
uninstall: $(UNINSTALL32)
rm -f $(vpidir)/cadpli.vpl
uninstall32:
ifeq (@enable_vvp32@,yes)
include $(srcdir)/enable_vvp32.mk
endif
-include $(patsubst %.o, dep/%.d, $O)
-120
View File
@@ -1,120 +0,0 @@
/*
* Copyright (c) 2003 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
* 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: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
#endif
# include <vpi_user.h>
# include <veriuser.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <string.h>
# include <assert.h>
# include "ivl_dlfcn.h"
typedef void* (*funcvp)(void);
static void thunker_register(void)
{
struct t_vpi_vlog_info vlog_info;
void*mod;
void*boot;
struct t_tfcell*tf;
int idx;
vpi_get_vlog_info(&vlog_info);
for (idx = 0 ; idx < vlog_info.argc ; idx += 1) {
char*module, *cp, *bp;
if (strncmp("-cadpli=", vlog_info.argv[idx], 8) != 0)
continue;
cp = vlog_info.argv[idx] + 8;
assert(cp);
bp = strchr(cp, ':');
assert(bp);
module = malloc(bp-cp+1);
strncpy(module, cp, bp-cp);
module[bp-cp] = 0;
mod = ivl_dlopen(module);
if (mod == 0) {
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
free(module);
continue;
}
bp += 1;
boot = ivl_dlsym(mod, bp);
if (boot == 0) {
vpi_printf("%s: Symbol %s not found.\n",
vlog_info.argv[idx], bp);
free(module);
continue;
}
free(module);
assert(boot);
tf = (*((funcvp)boot))();
assert(tf);
veriusertfs_register_table(tf);
}
}
void (*vlog_startup_routines[])() = {
thunker_register,
0
};
/*
* $Log: cadpli.c,v $
* Revision 1.7 2004/09/10 00:15:45 steve
* Remove bad casts.
*
* Revision 1.6 2004/09/05 21:19:51 steve
* Better type safety.
*
* Revision 1.5 2003/08/26 16:26:02 steve
* ifdef idents correctly.
*
* Revision 1.4 2003/04/30 01:28:06 steve
* Remove veriusertfs stuf.
*
* Revision 1.3 2003/02/22 04:04:38 steve
* Only include malloc.h if it is present.
*
* Revision 1.2 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
* Revision 1.1 2003/02/16 02:23:54 steve
* Add the cadpli interface module.
*
*/
-48
View File
@@ -1,48 +0,0 @@
CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by
Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run
third-party modules that were compiled to interface with XL or
NC. Obviously, this only works on the operating system that the PLI
application was compiled to run on. For example, a Linux module can
only be loaded and run under Linux.
Icarus Verilog uses an interface module, the "cadpli" module, to
connect the worlds. This module is installed with Icarus Verilog, and
is invoked by the usual -m flag to iverilog or vvp. This module in
turn scans the extended arguments, looking for +cadpli= arguments. The
latter specify the share object and bootstrap function for running the
module. For example, to run the module product.so, that has the
bootstrap function "my_boot":
vvp -mcadpli a.out -cadpli=./product.so:my_boot
The "-mcadpli" argument causes vvp to load the cadpli.vpl library
module. This activates the -cadpli= argument interpreter. The
-cadpli=<module>:<boot_func> argument, then, causes vvp, through the
cadpli module, to load the loadable PLI application, invoke the
my_boot function to get a veriusertfs table, and scan that table to
register the system tasks and functions exported by that object. The
format of the -cadpli= extended argument is essentially the same as
the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise.
$Log: cadpli.txt,v $
Revision 1.2 2003/02/17 00:01:25 steve
Use a variant of ivl_dlfcn to do dynamic loading
from within the cadpli module.
Change the +cadpli flag to -cadpli, to keep the
plusargs namespace clear.
Revision 1.1 2003/02/16 02:44:47 steve
Add the cadpli HOWTO.
-76
View File
@@ -1,76 +0,0 @@
AC_INIT(Makefile.in)
AC_PROG_CC
AC_PROG_CXX
AC_CHECK_TOOL(STRIP, strip, true)
AC_EXEEXT
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AC_PROG_INSTALL
# vvp32 is by default disabled
#enable_vvp32=no
AC_SUBST(enable_vvp32)
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
# --
# Look for a dl library to use. First look for the standard dlopen
# functions, and failing that look for the HP specific shl_load function.
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
DLLIB=''
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
if test -z "$DLLIB" ; then
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
fi
AC_SUBST(DLLIB)
AX_CPP_PRECOMP
# Compiler option for position independent code, needed when making shared objects.
AX_C_PICFLAG
# Linker option used when compiling the target
AX_LD_RDYNAMIC
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
AX_LD_EXTRALIBS
#######################
## test for underscores. The vpi module loader in vvm needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AX_C_UNDERSCORES_LEADING
AX_C_UNDERSCORES_TRAILING
#######################
## end of test for underscores
#######################
AX_CPP_IDENT
# where to put vpi subdirectories
AC_MSG_CHECKING(for VPI subdirectories)
if test x${vpidir1} = x
then
vpidir1="."
fi
AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
AC_OUTPUT(Makefile)
-39
View File
@@ -1,39 +0,0 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library 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
#
#ident "$Id: enable_vvp32.mk,v 1.1 2003/10/09 01:07:20 steve Exp $"
#
all32: bin32 bin32/cadpli.vpl
bin32:
mkdir bin32
bin32/%.o: %.c
$(CC) -m32 -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
bin32/cadpli.vpl: $(addprefix bin32/,$O) ../vvp/bin32/libvpi.a ../libveriuser/bin32/libveriuser.o
$(CC) $(SHARED) -m32 -o $@ $(addprefix bin32/,$O) ../libveriuser/bin32/libveriuser.o ../vvp/bin32/libvpi.a
install32: all32 $(vpidir32)/cadpli.vpl
$(vpidir32)/cadpli.vpl: bin32/cadpli.vpl
$(INSTALL_PROGRAM) bin32/cadpli.vpl $(vpidir32)/cadpli.vpl
uninstall32:
rm -f $(vpidir32)/cadpli.vpl
+9 -4
View File
@@ -1,4 +1,9 @@
functor:cprop
functor:nodangle
-t:dll
flag:DLL=tgt-vvp/vvp.tgt
# The make check target uses this to check the compilation of the
# compiler.
[-tvvm-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
[-tvvp-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
+27 -139
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2004 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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
@@ -18,22 +18,22 @@
* 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: compiler.h,v 1.33 2007/04/19 02:52:53 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: compiler.h,v 1.7 2001/11/16 05:07:19 steve Exp $"
#endif
# include <list>
# include <map>
# include "netlist.h"
# include "StringHeap.h"
/*
* This defines constants and defaults for the compiler in general.
*/
/* The integer_width is the width of integer variables. */
extern unsigned integer_width;
/* The INTEGER_WIDTH is the default width of integer variables, and
the presumed width of unsigned literal numbers. */
#ifndef INTEGER_WIDTH
# define INTEGER_WIDTH 32
#endif
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
@@ -61,155 +61,43 @@ extern unsigned integer_width;
/*
* These are flags to enable various sorts of warnings. By default all
* the warnings are off, the -W<list> parameter arranges for each to be
* enabled.
* the warnings are of, the -W<list> parameter arranges for each to be
* enabled.
*/
/* Implicit definitions of wires. */
extern bool warn_implicit;
extern bool error_implicit;
/* inherit timescales across files. */
extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_synth2;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
/* This is an ordered list of library suffixes to search. */
/* This is an ordered list of libraries to search. */
extern list<const char*>library_dirs;
extern list<const char*>library_suff;
extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
support. Then there are also more detailed controls for more
specific language features. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001 = 2,
GN_VER2001X = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
extern bool gn_cadence_types_flag;
/* These functions test that specific features are enabled. */
inline bool gn_cadence_types_enabled()
{ return gn_cadence_types_flag && generation_flag==GN_VER2001X; }
/* If this flag is true, then elaborate specify blocks. If this flag
is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
extern map<perm_string,unsigned> missing_modules;
/* Files that are library files are in this map. The lexor compares
file names as it processes `line directives, and if the file name
matches an entry in this table, it will turn on the
library_active_flag so that modules know that they are in a
library. */
extern map<string,bool> library_file_map;
/*
* the lex_strings are perm_strings made up of tokens from the source
* file. Identifiers are so likely to be used many times that it makes
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
extern StringHeap misc_strings;
/*
* system task/function listings.
*/
/*
* This table describes all the return values of various system
* functions. This table is used to elaborate expressions that are
* system function calls.
*/
struct sfunc_return_type {
const char* name;
ivl_variable_type_t type;
unsigned wid;
int signed_flag;
};
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path);
/*
* $Log: compiler.h,v $
* Revision 1.33 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
* Revision 1.7 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.32 2007/03/07 04:24:59 steve
* Make integer width controllable.
* Revision 1.6 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.31 2006/09/28 04:35:18 steve
* Support selective control of specify and xtypes features.
* Revision 1.5 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.30 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
* Revision 1.4 2000/08/20 04:13:56 steve
* Add ivl_target support for logic gates, and
* make the interface more accessible.
*
* Revision 1.29 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
* Revision 1.3 2000/03/17 21:50:25 steve
* Switch to control warnings.
*
* Revision 1.28 2005/06/28 04:25:55 steve
* Remove reference to SystemVerilog.
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.27 2005/04/24 23:44:01 steve
* Update DFF support to new data flow.
* Revision 1.1 1999/06/06 20:42:48 steve
* Make compiler width a compile time constant.
*
* Revision 1.26 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.25 2004/09/25 01:58:44 steve
* Add a debug_elaborate flag
*
* Revision 1.24 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.23 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.22 2004/03/10 04:51:24 steve
* Add support for system function table files.
*
* Revision 1.21 2004/03/09 04:29:42 steve
* Separate out the lookup_sys_func table, for eventual
* support for function type tables.
*
* Remove ipal compile flags.
*
* Revision 1.20 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.19 2003/11/13 05:55:33 steve
* Move the DLL= flag to target config files.
*
* Revision 1.18 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*
* Revision 1.17 2003/09/25 00:25:14 steve
* Summary list of missing modules.
*
* Revision 1.16 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*/
#endif
+367 -548
View File
File diff suppressed because it is too large Load Diff
+4 -35
View File
@@ -18,8 +18,8 @@
* 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: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
#if !defined(WINNT)
#ident "$Id: config.h.in,v 1.4 2002/02/16 03:18:53 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -31,54 +31,23 @@
#endif
# undef NEED_LU
# undef NEED_TU
# undef NEED_TU
# undef WLU
# undef WTU
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_INTTYPES_H
# undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
# undef HAVE_FCHMOD
# undef HAVE_LIBREADLINE
# undef HAVE_LIBZ
# undef HAVE_LIBBZ2
# undef HAVE_SYS_WAIT_H
# undef WORDS_BIGENDIAN
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
# undef ENABLE_VVM
/*
* $Log: config.h.in,v $
* Revision 1.12 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*
* Revision 1.11 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.10 2003/08/26 16:26:01 steve
* ifdef idents correctly.
*
* Revision 1.9 2003/07/03 16:29:55 steve
* spemm WORDS_BIGENDIAN correctly.
*
* Revision 1.8 2003/03/07 02:44:33 steve
* Implement $realtobits.
*
* Revision 1.7 2003/02/20 00:49:24 steve
* detect -lz and -lbz2 libraries.
*
* Revision 1.6 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
* Revision 1.4 2002/02/16 03:18:53 steve
* Make vvm optional, normally off.
*
Vendored
+129 -318
View File
@@ -1,10 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002 Free Software Foundation, Inc.
timestamp='2002-07-03'
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
# Free Software Foundation, Inc.
#
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
@@ -29,8 +27,8 @@ timestamp='2002-07-03'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <[email protected]>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Written by Per Bothner <[email protected]>.
# Please send patches to <[email protected]>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -52,73 +50,30 @@ timestamp='2002-07-03'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
nto-qnx* | linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -144,7 +99,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis)
-apple)
os=
basic_machine=$1
;;
@@ -158,14 +113,6 @@ case $os in
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
@@ -224,58 +171,30 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa64 | mipsisa64el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| hppa64 \
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
| alphaev6[78] \
| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
| thumb | d10v | fr30 | avr)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
i[34567]86)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
@@ -284,54 +203,28 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipstx39 | mipstx39el \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| hppa2.0n-* | hppa64-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
| alphaev6[78]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f301-* | armv*-* | s390-* | sv1-* | t3e-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
| bs2000-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -368,14 +261,14 @@ case $basic_machine in
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
basic_machine=m68k-cbm
;;
amigaos | amigados)
basic_machine=m68k-unknown
basic_machine=m68k-cbm
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
basic_machine=m68k-cbm
os=-sysv4
;;
apollo68)
@@ -394,10 +287,6 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -418,30 +307,27 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -483,10 +369,6 @@ case $basic_machine in
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
@@ -562,19 +444,19 @@ case $basic_machine in
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
i[34567]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
i[34567]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
i[34567]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
i[34567]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
@@ -586,6 +468,14 @@ case $basic_machine in
basic_machine=i386-unknown
os=-vsta
;;
i386-go32 | go32)
basic_machine=i386-unknown
os=-go32
;;
i386-mingw32 | mingw32)
basic_machine=i386-unknown
os=-mingw32
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -611,10 +501,6 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -622,6 +508,14 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -636,12 +530,8 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
basic_machine=i386-unknown
os=-msdos
;;
mvs)
@@ -705,10 +595,6 @@ case $basic_machine in
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
@@ -719,10 +605,6 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -748,28 +630,28 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
pentium | p5 | k5 | k6 | nexen)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
pentiumpro | p6 | 6x86)
basic_machine=i686-pc
;;
pentiumii | pentium2)
basic_machine=i686-pc
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
pentium-* | p5-* | k5-* | k6-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
pentiumpro-* | p6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
power) basic_machine=rs6000-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
@@ -781,23 +663,9 @@ case $basic_machine in
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -808,12 +676,6 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
@@ -825,7 +687,7 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs | simso-wrs)
sparclite-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -883,7 +745,7 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
sv1)
basic_machine=sv1-cray
os=-unicos
;;
@@ -891,32 +753,16 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e)
basic_machine=alphaev5-cray
basic_machine=t3e-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -963,17 +809,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -994,6 +836,13 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
@@ -1003,23 +852,13 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
sparc | sparcv9)
basic_machine=sparc-sun
;;
cydra)
@@ -1041,9 +880,6 @@ case $basic_machine in
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -1100,19 +936,15 @@ case $os in
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
| -openstep* | -oskit*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
x86-* | i[34567]86-*)
;;
*)
os=-nto$os
@@ -1129,6 +961,9 @@ case $os in
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
@@ -1156,22 +991,16 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
-nsk)
os=-nsk
;;
# Preserve the version number of sinix5.
@@ -1208,7 +1037,7 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-*mint | -*MiNT)
os=-mint
;;
-none)
@@ -1242,10 +1071,6 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
@@ -1273,9 +1098,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1357,7 +1179,7 @@ case $basic_machine in
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
f301-fujitsu)
os=-uxpv
;;
*-rom68k)
@@ -1423,7 +1245,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks* | -windiss*)
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
@@ -1435,23 +1257,12 @@ case $basic_machine in
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-*mint | -*MiNT)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
+174 -71
View File
@@ -1,9 +1,17 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(_pli_types.h)
AC_CANONICAL_HOST
AC_ARG_ENABLE(vvm, vvm target -- the obsolete vvm code generator,
AC_DEFINE(ENABLE_VVM))
if test "${enable_vvm+set}" = set
then
ENABLE_VVM=yes
else
ENABLE_VVM=no
fi
AC_SUBST(ENABLE_VVM)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
@@ -11,13 +19,9 @@ AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_PROGS(XGPERF,gperf,none)
if test "$XGPERF" = "none"
then
echo ""
echo "*** Warning: No suitable gperf found. ***"
echo " The gperf package is essential for building ivl from"
echo " CVS sources, or modifying the parse engine of ivl itself."
echo " You can get away without it when simply building from"
echo " snapshots or major releases."
echo ""
echo "*** Error: No suitable gperf found. ***"
echo " Please install the 'gperf' package."
exit 1
fi
AC_CHECK_PROGS(LEX,flex,none)
@@ -36,29 +40,9 @@ then
exit 1
fi
AC_EXEEXT
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
# vvp32 is by default disabled
#enable_vvp32=no
AC_SUBST(enable_vvp32)
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
AC_CHECK_LIB(z, gzwrite)
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
AC_SUBST(HAVE_LIBZ)
if test "$WIN32" = "yes"; then
AC_CHECK_LIB(bz2, main)
else
AC_CHECK_LIB(bz2, BZ2_bzdopen)
fi
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
@@ -66,11 +50,20 @@ AC_TRY_LINK(
#include <sys/times.h>
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
do_times=yes
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
AC_DEFINE(HAVE_TIMES,1),
do_times=no
)
AC_MSG_RESULT($do_times)
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
AC_ARG_WITH(ipal,enable PAL target,
if test "$with_ipal" = no; then
echo Disabling ipal support
HAVE_IPAL=
fi
)
AC_SUBST(HAVE_IPAL)
# --
# Look for a dl library to use. First look for the standard dlopen
# functions, and failing that look for the HP specific shl_load function.
@@ -87,61 +80,171 @@ AC_SUBST(DLLIB)
AC_PROG_INSTALL
AC_LANG_C
AC_C_BIGENDIAN
AC_CANONICAL_HOST
# $host
AX_LD_EXTRALIBS
# Compiler option for position independent code, needed when making shared objects.
# CFLAGS inherited by cadpli/Makefile?
AX_C_PICFLAG
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# Linker option used when compiling the target
AX_LD_RDYNAMIC
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
#######################
## test for underscores. The vpi module loader needs to know this
## test for underscores. The vpi module loader in vvm needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AX_C_UNDERSCORES_LEADING
AX_C_UNDERSCORES_TRAILING
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
WIN32=no
AC_MSG_CHECKING("Checking for windows")
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
AC_MSG_CHECKING("for leading and/or trailing underscores")
cat << EOF > underscore.c
void underscore(void){}
EOF
$CC -shared -c underscore.c > /dev/null 2>&1
CC_LEADING_UNDERSCORE=no
CC_TRAILING_UNDERSCORE=no
output=`nm underscore.o|grep _underscore 2>&1`
if test ! -z "$output" -a -z "$CYGWIN" -a -z "$MINGW32"; then
CC_LEADING_UNDERSCORE=yes
AC_DEFINE(NEED_LU)
fi
output=`nm underscore.o|grep underscore_ 2>&1`
if test ! -z "$output"; then
CC_TRAILING_UNDERSCORE=yes
AC_DEFINE(NEED_TU)
fi
if test "$CC_LEADING_UNDERSCORE" = yes; then
AC_DEFINE(WLU)
fi
if test "$CC_TRAILING_UNDERSCORE" = yes; then
AC_DEFINE(WTU)
fi
rm underscore.c underscore.o
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
#######################
## end of test for underscores
#######################
AX_CPP_IDENT
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
# If not otherwise specified, set the libdir64 variable
# to the same as libdir.
AC_MSG_CHECKING(for libdir64 path)
if test x${libdir64} = x
then
libdir64="${libdir}"
fi
AC_SUBST(libdir64)
AC_MSG_RESULT(${libdir64})
AC_MSG_CHECKING("for flag to make position independent code")
PICFLAG=-fPIC
case "${host}" in
# where to put vpi subdirectories
AC_MSG_CHECKING(for VPI subdirectories)
if test x${vpidir1} = x
then
vpidir1="."
fi
*-*-cygwin*)
PICFLAG=
;;
AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
*-*-hpux*)
PICFLAG=+z
;;
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp libveriuser cadpli)
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
# mingw needs to link with libiberty.a, cygwin can tolerate it
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
EXTRALIBS="-liberty"
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp"
CFLAGS="-no-cpp-precomp"
;;
esac
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_MSG_CHECKING("for -rdynamic compiler flag")
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
AC_MSG_RESULT($strip_dynamic)
AC_MSG_CHECKING("for shared library link flag")
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+298 -267
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2005 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -16,8 +16,8 @@
* 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: cprop.cc,v 1.56 2007/03/07 00:38:15 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cprop.cc,v 1.32 2002/02/03 00:06:28 steve Exp $"
#endif
# include "config.h"
@@ -30,7 +30,7 @@
/*
* The cprop function below invokes constant propagation where
* The cprop function below invokes constant propogation where
* possible. The elaboration generates NetConst objects. I can remove
* these and replace the gates connected to it with simpler ones. I
* may even be able to replace nets with a new constant.
@@ -55,6 +55,86 @@ void cprop_functor::signal(Design*des, NetNet*obj)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute("LPM_Direction") != "ADD")
return;
// If the low bit on the A side is 0, then eliminate it from
// the adder, and pass the B side directly to the
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataA(0))
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataB(0))
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataA(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// If the adder is only 1 bit wide, then replace it with the
// simple logic gate.
if (obj->width() == 1) {
NetLogic*tmp;
if (obj->pin_Cout().is_linked()) {
tmp = new NetLogic(obj->scope(),
des->local_symbol(obj->name()), 3,
NetLogic::AND);
connect(tmp->pin(0), obj->pin_Cout());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
des->add_node(tmp);
}
tmp = new NetLogic(obj->scope(), obj->name(), 3, NetLogic::XOR);
connect(tmp->pin(0), obj->pin_Result(0));
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
@@ -73,37 +153,19 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope();
unsigned const_count = 0;
bool unknown_flag = false;
/* First, look for the case where constant bits on matching A
and B inputs are different. This this is so, the device can
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
if (! link_drivers_constant(obj->pin_DataA(idx)))
continue;
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
if (! link_drivers_constant(obj->pin_DataB(idx)))
continue;
const_count += 1;
verinum::V abit = obj->pin_DataA(idx).nexus()->driven_value();
verinum::V bbit = obj->pin_DataB(idx).nexus()->driven_value();
if ((abit == verinum::V0) && (bbit == verinum::V0))
continue;
if ((abit == verinum::V1) && (bbit == verinum::V1))
continue;
unknown_flag = true;
if ((abit == verinum::Vz) || (abit == verinum::Vx))
continue;
if ((bbit == verinum::Vz) || (bbit == verinum::Vx))
if (driven_value(obj->pin_DataA(idx)) ==
driven_value(obj->pin_DataB(idx)))
continue;
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
@@ -114,31 +176,16 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
return;
}
/* If all the inputs are constant, then at this point the
result is either V1 or Vx. */
if (const_count == obj->width()) {
NetConst*val = new NetConst(scope, obj->name(),
unknown_flag
? verinum::Vx
: verinum::V1);
connect(val->pin(0), obj->pin_AEB());
delete obj;
des->add_node(val);
count += 1;
return;
}
/* Still may need the gate. Run through the inputs again, and
look for pairs of constants. Those inputs can be removed. */
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin_DataA(idx))) {
idx += 1;
continue;
}
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin_DataB(idx))) {
idx += 1;
continue;
}
@@ -170,7 +217,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR, 1);
NetLogic::XNOR);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
@@ -193,38 +240,66 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
delete obj;
des->add_node(tmp);
count += 1;
#endif
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
{
// Look for and count unlinked FF outputs. Note that if the
// Data and Q pins are connected together, they can be removed
// from the circuit, since it doesn't do anything.
// from the circuit.
unsigned unlinked_count = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))) {
obj->pin_Data(idx).unlink();
obj->pin_Q(idx).unlink();
}
if (! obj->pin_Q(idx).is_linked())
unlinked_count += 1;
}
if (connected(obj->pin_Data(), obj->pin_Q())
&& (! obj->pin_Sclr().is_linked())
&& (! obj->pin_Sset().is_linked())
&& (! obj->pin_Aclr().is_linked())
&& (! obj->pin_Aset().is_linked())) {
obj->pin_Data().unlink();
obj->pin_Q().unlink();
// If the entire FF is unlinked, remove the whole thing.
if (unlinked_count == obj->width()) {
delete obj;
count += 1;
return;
}
// If some of the FFs are unconnected, make a new FF array
// that does not include the useless FF devices.
if (unlinked_count > 0) {
NetFF*tmp = new NetFF(obj->scope(), obj->name(),
obj->width()-unlinked_count);
connect(tmp->pin_Clock(), obj->pin_Clock());
connect(tmp->pin_Enable(), obj->pin_Enable());
connect(tmp->pin_Aload(), obj->pin_Aload());
connect(tmp->pin_Aset(), obj->pin_Aset());
connect(tmp->pin_Aclr(), obj->pin_Aclr());
connect(tmp->pin_Sload(), obj->pin_Sload());
connect(tmp->pin_Sset(), obj->pin_Sset());
connect(tmp->pin_Sclr(), obj->pin_Sclr());
unsigned tidx = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
if (obj->pin_Q(idx).is_linked()) {
connect(tmp->pin_Data(tidx), obj->pin_Data(idx));
connect(tmp->pin_Q(tidx), obj->pin_Q(idx));
tidx += 1;
}
assert(tidx == obj->width() - unlinked_count);
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
#if 0
NetScope*scope = obj->scope();
#endif
switch (obj->type()) {
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NAND:
case NetLogic::AND: {
unsigned top = obj->pin_count();
@@ -235,12 +310,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an AND gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin(idx))) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
if (driven_value(obj->pin(idx)) == verinum::V1) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -251,7 +326,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
if (driven_value(obj->pin(idx)) != verinum::V0) {
idx += 1;
xs += 1;
continue;
@@ -273,10 +348,6 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -302,10 +373,6 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -339,21 +406,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::AND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
break;
case NetLogic::NAND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -365,16 +427,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
/* Finally, this cleans up the gate by creating a
new [N]AND gate that has the right number of
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
obj->type());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -387,12 +445,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NOR:
case NetLogic::OR: {
@@ -404,12 +457,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an OR gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin(idx))) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
if (driven_value(obj->pin(idx)) == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -420,7 +473,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
if (driven_value(obj->pin(idx)) != verinum::V1) {
idx += 1;
continue;
}
@@ -441,10 +494,6 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -470,10 +519,6 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -492,20 +537,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::OR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
break;
case NetLogic::NOR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -514,7 +555,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
delete obj;
count += 1;
return;
v }
}
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
@@ -522,11 +563,7 @@ v }
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
obj->type());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -539,12 +576,7 @@ v }
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::XNOR:
case NetLogic::XOR: {
unsigned top = obj->pin_count();
@@ -556,12 +588,12 @@ v }
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin(idx))) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
if (driven_value(obj->pin(idx)) == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -586,12 +618,12 @@ v }
unsigned one = 0, ones = 0;
idx = 1;
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
if (! link_drivers_constant(obj->pin(idx))) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
if (driven_value(obj->pin(idx)) == verinum::V1) {
if (one == 0) {
one = idx;
ones += 1;
@@ -599,8 +631,6 @@ v }
continue;
}
/* Here we found two constant V1
inputs. Unlink both. */
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -615,11 +645,8 @@ v }
obj->pin(top).unlink();
}
/* Reset ones counter and one index,
start looking for the next pair. */
assert(ones == 1);
ones = 0;
one = 0;
continue;
}
@@ -634,10 +661,6 @@ v }
: verinum::V0;
NetConst*tmp = new NetConst(scope, obj->name(), out);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -654,9 +677,9 @@ v }
if ((top == 3) && (ones == 1)) {
unsigned save;
if (! obj->pin(1).nexus()->drivers_constant())
if (! link_drivers_constant(obj->pin(1)))
save = 1;
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
else if (driven_value(obj->pin(1)) != verinum::V1)
save = 1;
else
save = 2;
@@ -666,15 +689,11 @@ v }
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
NetLogic::BUF);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
@@ -695,15 +714,11 @@ v }
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
NetLogic::NOT);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
@@ -721,7 +736,7 @@ v }
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
obj->type());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -734,56 +749,14 @@ v }
}
break;
}
#endif
default:
break;
}
}
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, type, obj->width());
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
rsig->data_type(IVL_VT_LOGIC);
connect(tmp->pin(2), rsig->pin(0));
}
delete obj;
}
/*
* This detects the case where the mux selects between a value and
* This detects the case where the mux selects between a value an
* Vz. In this case, replace the device with a bufif with the sel
* input used to enable the output.
*/
@@ -798,36 +771,64 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
NetMux with an array of BUFIF1 devices, with the enable
connected to the select input. */
bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 0))) {
flag = false;
break;
}
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
flag = false;
}
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
flag = false;
if (driven_value(obj->pin_Data(idx, 0)) != verinum::Vz) {
flag = false;
break;
}
}
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF1);
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(),
des->local_symbol(obj->name()),
3, NetLogic::BUFIF1);
connect(obj->pin_Result(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
}
count += 1;
delete obj;
return;
}
/* If instead the second input is all constant Vz, replace the
NetMux with an array of BUFIF0 devices. */
flag = true;
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
flag = false;
}
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 1))) {
flag = false;
break;
}
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
flag = false;
if (driven_value(obj->pin_Data(idx, 1)) != verinum::Vz) {
flag = false;
break;
}
}
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF0);
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(),
des->local_symbol(obj->name()),
3, NetLogic::BUFIF0);
connect(obj->pin_Result(idx), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
}
count += 1;
delete obj;
return;
}
}
@@ -846,7 +847,7 @@ struct cprop_dc_functor : public functor_t {
void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
{
// 'bz constant values drive high impedance to whatever is
// connected to it. In other words, it is a noop.
// connected to it. In otherwords, it is a noop.
{ unsigned tmp = 0;
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (obj->value(idx) == verinum::Vz) {
@@ -906,17 +907,10 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
assert(tmp->scope());
// If the net is a signal name from the source,
// then users will probably want to see it in the
// waveform dump, so unhooking the constant will
// make it look wrong.
if (! tmp->local_flag())
return;
// If the net has an eref, then there is an
// expression somewhere that reads this signal. So
// the constant does get read.
if (tmp->peek_eref() > 0)
if (tmp->get_eref() > 0)
return;
// If the net is a port of the root module, then
@@ -936,7 +930,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
void cprop(Design*des)
{
// Continually propagate constants until a scan finds nothing
// Continually propogate constants until a scan finds nothing
// to do.
cprop_functor prop;
do {
@@ -950,79 +944,116 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.56 2007/03/07 00:38:15 steve
* Lint fixes.
* Revision 1.32 2002/02/03 00:06:28 steve
* Comments about xor evaluation.
*
* Revision 1.55 2006/05/24 04:32:57 steve
* Fix handling of ternary-to-bufif0 constant propagation.
* Revision 1.31 2001/12/31 01:56:08 steve
* Get sense of 1-bit == operator right.
*
* Revision 1.54 2005/07/15 19:22:52 steve
* bufif enable is LOGIC.
* Revision 1.30 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.53 2005/05/15 04:44:30 steve
* Disable obsolete logic constant fixup code.
* Revision 1.29 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.52 2005/04/24 23:44:01 steve
* Update DFF support to new data flow.
* Revision 1.28 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.51 2005/02/12 22:52:45 steve
* Fix copyright notice.
* Revision 1.27 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.50 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
* Revision 1.26 2001/02/18 01:07:32 steve
* check signals in the cprop functor.
*
* Revision 1.49 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
* Revision 1.25 2001/02/16 03:27:31 steve
* Constant propagation for compare ==.
*
* Revision 1.48 2004/12/11 02:31:25 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.24 2001/02/10 04:50:54 steve
* Catch constants driving root module ports. (PR#130)
*
* Revision 1.47 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings.
* Revision 1.23 2000/12/30 03:11:15 steve
* Propagate initial value of constants into wires.
*
* Revision 1.46 2003/11/08 17:53:34 steve
* Do not remove constants accessible to VPI.
* Revision 1.22 2000/11/23 01:55:52 steve
* Propagate constants through xnor gates. (PR#51)
*
* Revision 1.45 2003/10/31 02:40:06 steve
* Donot elide FF that has set or clr connections.
* Revision 1.21 2000/11/19 05:26:58 steve
* Replace AND constand propagation.
*
* Revision 1.44 2003/04/25 05:06:32 steve
* Handle X values in constant == nets.
* Revision 1.20 2000/11/18 05:13:27 steve
* Thorough constant propagation for or and nor gates.
*
* Revision 1.43 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
* Revision 1.19 2000/11/18 04:10:37 steve
* Handle constant propagation through XOR gates,
* including reducing the gate to a constant,
* a buffer or an inverter if possible.
*
* Revision 1.42 2003/02/26 01:29:24 steve
* LPM objects store only their base names.
* Revision 1.18 2000/11/11 00:03:36 steve
* Add support for the t-dll backend grabing flip-flops.
*
* Revision 1.41 2003/01/30 16:23:07 steve
* Spelling fixes.
* Revision 1.17 2000/10/07 19:45:42 steve
* Put logic devices into scopes.
*
* Revision 1.40 2003/01/27 05:09:17 steve
* Spelling fixes.
* Revision 1.16 2000/10/06 21:26:34 steve
* Eliminate zero inputs to xor.
*
* Revision 1.39 2002/08/20 04:12:22 steve
* Copy gate delays when doing gate delay substitutions.
* Revision 1.15 2000/08/02 14:48:01 steve
* use bufif0 if z is in true case of mux.
*
* Revision 1.38 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
* Revision 1.14 2000/07/25 02:55:13 steve
* Unlink z constants from nets.
*
* Revision 1.37 2002/06/25 01:33:22 steve
* Cache calculated driven value.
* Revision 1.13 2000/07/15 05:13:43 steve
* Detect muxing Vz as a bufufN.
*
* Revision 1.36 2002/06/24 01:49:38 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
* Revision 1.12 2000/06/25 19:59:41 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.
*
* Revision 1.35 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
* Revision 1.11 2000/06/24 22:55:19 steve
* Get rid of useless next_link method.
*
* Revision 1.10 2000/05/14 17:55:04 steve
* Support initialization of FF Q value.
*
* Revision 1.9 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.8 2000/04/28 21:00:28 steve
* Over agressive signal elimination in constant probadation.
*
* Revision 1.7 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 2000/01/02 17:56:42 steve
* Do not delete constants that input to exressions.
*
* Revision 1.5 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.4 1999/12/17 06:18:15 steve
* Rewrite the cprop functor to use the functor_t interface.
*
* Revision 1.3 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.2 1998/12/02 04:37:13 steve
* Add the nobufz function to eliminate bufz objects,
* Object links are marked with direction,
* constant propagation is more careful will wide links,
* Signal folding is aware of attributes, and
* the XNF target can dump UDP objects based on LCA
* attributes.
*
* Revision 1.1 1998/11/13 06:23:17 steve
* Introduce netlist optimizations with the
* cprop function to do constant propogation.
*
* Divide signal reference counts between rval
* and lval references.
*/
+29 -35
View File
@@ -1,35 +1,29 @@
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
Note: Icarus Verilog also compiles to native Windows binaries if you
use the instructions in the mingw.txt file. Some people prefer cygwin
binaries, and these instructions apply.
To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
Procedure:
o Get the source code - see the main Icarus Verilog page for how to
do this
o cd to the verilog directory
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <[email protected]>
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
Procedure:
o Get the source code - see the main icarus verilog page for how to
do this
o cd to the verilog directory
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <[email protected]>
+132 -586
View File
File diff suppressed because it is too large Load Diff
+2 -15
View File
@@ -15,10 +15,9 @@
* 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
*
* $Id: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
#endif
/*
* This is a simple program to make a dosified copy of the
@@ -69,18 +68,6 @@ int main(int argc, char*argv[])
/*
* $Log: dosify.c,v $
* Revision 1.5 2003/07/15 16:17:47 steve
* Fix spelling of ifdef.
*
* Revision 1.4 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
-2
View File
@@ -1,2 +0,0 @@
Makefile
iverilog-vpi.exe
-80
View File
@@ -1,80 +0,0 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library 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
#
#ident "$Id: Makefile.in,v 1.7 2004/10/13 22:01:34 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.8
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@
clean:
rm -f *.o
rm -f iverilog-vpi@EXEEXT@
distclean: clean
rm -f Makefile
O = main.o res.o
iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
main.o: main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
# Windows specific...
res.o: res.rc
windres -i res.rc -o res.o
#
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
uninstall:
rm -f $(bindir)/iverilog-vpi@EXEEXT@
-573
View File
@@ -1,573 +0,0 @@
/*
* Copyright (c) 2002 Gus Baldauf ([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
* 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
*/
/*
* iverilog-vpi.c
*
* this program provides the functionality of iverilog-vpi.sh under Win32
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
/* Macros used for compiling and linking */
#define IVERILOG_VPI_CC "gcc" /* no .exe extension */
#define IVERILOG_VPI_CXX "gcc" /* no .exe extension */
#define IVERILOG_VPI_CFLAGS "-O" /* -I appended later */
#define IVERILOG_VPI_LD "gcc" /* no .exe extension */
#define IVERILOG_VPI_LDFLAGS "-shared -Wl,--enable-auto-image-base"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi" /* -L prepended later */
/* pointers to global strings */
static struct global_strings {
char *pCCSRC; /* list of C source files */
char *pCXSRC; /* list of C++ source files */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
char *pMINGW; /* path to MinGW directory */
char *pIVL; /* path to IVL directory */
char *pCFLAGS; /* CFLAGS option */
char *pLDLIBS; /* LDLIBS option */
char *pNewPath; /* new PATH environment variable setting */
} gstr;
static void deInitDynString(char *str)
{
free(str);
}
/* when finished, free allocated memory and return error code */
static void myExit(int exitVal)
{
deInitDynString(gstr.pCCSRC);
deInitDynString(gstr.pCXSRC);
deInitDynString(gstr.pOBJ);
deInitDynString(gstr.pLIB);
deInitDynString(gstr.pOUT);
deInitDynString(gstr.pMINGW);
deInitDynString(gstr.pIVL);
deInitDynString(gstr.pCFLAGS);
deInitDynString(gstr.pLDLIBS);
deInitDynString(gstr.pNewPath);
exit(exitVal);
}
/* display usage summary and exit */
static void usage()
{
fprintf(stderr,"usage: iverilog-vpi [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n");
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
myExit(1);
}
static void initDynString(char **str)
{
*str = (char *) malloc(1);
if (!*str) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
*str[0] = 0;
}
/* initialize dynamic memory buffers */
static void init()
{
initDynString(&gstr.pCCSRC);
initDynString(&gstr.pCXSRC);
initDynString(&gstr.pOBJ);
initDynString(&gstr.pLIB);
initDynString(&gstr.pOUT);
initDynString(&gstr.pMINGW);
initDynString(&gstr.pIVL);
initDynString(&gstr.pCFLAGS);
initDynString(&gstr.pLDLIBS);
initDynString(&gstr.pNewPath);
}
/* return true if "str" is terminated with with "end", case insensitive */
static int endsIn (char *end, char *str)
{
char *ext;
if (strlen(end) >= strlen(str))
return 0;
ext = str + (strlen(str) - strlen(end));
return stricmp(end,ext) ? 0 : 1;
}
/* return true if "str" begins with "prefix", case insensitive */
static int startsWith (char *prefix, char *str)
{
if (strlen(prefix) >= strlen(str))
return 0;
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
}
/* append "app" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "app" */
static void appendn (char **ptr, char *app, int count)
{
*ptr = (char *) realloc(*ptr,strlen(*ptr)+(count?count:strlen(app))+1);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
if (count)
strncat(*ptr,app,count);
else
strcat(*ptr,app);
}
/* append "app" to "ptr", allocating memory as needed */
static void append (char **ptr, char *app)
{
appendn(ptr,app,0);
}
/* if the string does not end with a backslash, add one */
static void appendBackSlash(char **str)
{
if ((*str)[strlen(*str)-1] != '\\')
append(str,"\\");
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "str" */
static void assignn (char **ptr, char *str, int count)
{
*ptr = (char *) realloc(*ptr,(count?count:strlen(str))+1);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
if (count) {
strncpy(*ptr,str,count);
(*ptr)[count] = 0;
}
else
strcpy(*ptr,str);
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
static void assign (char **ptr, char *str)
{
assignn(ptr,str,0);
}
/* get a copy of a Icarus Verilog registry string key */
static int GetRegistryKey(char *key, char **value)
{
long lrv;
HKEY hkKey;
char *regKeyBuffer;
DWORD regKeyType, regKeySize;
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
if (lrv != ERROR_SUCCESS)
return 0;
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,NULL,&regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
return 0;
}
regKeyBuffer = (char *) malloc(regKeySize+1);
if (!regKeyBuffer) {
lrv = RegCloseKey(hkKey);
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,regKeyBuffer,&regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
free(regKeyBuffer);
return 0;
}
RegCloseKey(hkKey);
assign(value,regKeyBuffer);
free(regKeyBuffer);
return 1;
}
/* store a copy of a Icarus Verilog registry string key */
static void SetRegistryKey(char *key, char *value)
{
HKEY hkKey;
DWORD res;
if (RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
"Software\\Icarus Verilog",
0,
"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,NULL,
&hkKey,
&res) != ERROR_SUCCESS)
return;
RegSetValueEx(hkKey,key,0,REG_SZ,value,strlen(value)+1);
RegCloseKey(hkKey);
printf("info: storing %s in Windows' registry entry\n",value);
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
}
/* parse the command line, assign results to global variable strings */
static int parse(int argc, char *argv[])
{
int idx, srcFileCnt=0;
char dot_c_ext[] = ".c";
char dot_cc_ext[] = ".cc";
char dot_cpp_ext[] = ".cpp";
char dot_o_ext[] = ".o";
char name_option[] = "--name=";
char lib_option[] = "-l";
char mingw_option[] = "-mingw=";
char ivl_option[] = "-ivl=";
if (argc == 1)
return 0;
for (idx=1; idx<argc; ++idx) {
if (endsIn(dot_c_ext,argv[idx])) { /* check for C source files */
++srcFileCnt;
append(&gstr.pCCSRC,argv[idx]);
append(&gstr.pCCSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_c_ext));
}
else if (endsIn(dot_cc_ext,argv[idx])) { /* check for C++ source files */
++srcFileCnt;
append(&gstr.pCXSRC,argv[idx]);
append(&gstr.pCXSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
}
else if (endsIn(dot_cpp_ext,argv[idx])) { /* check for C++ source files */
++srcFileCnt;
append(&gstr.pCXSRC,argv[idx]);
append(&gstr.pCXSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cpp_ext));
}
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
++srcFileCnt;
append(&gstr.pOBJ,argv[idx]);
append(&gstr.pOBJ," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_o_ext));
}
else if (startsWith(name_option,argv[idx])) { /* check for --name option */
assignn(&gstr.pOUT,argv[idx]+sizeof(name_option)-1,strlen(argv[idx])-(sizeof(name_option)-1));
}
else if (startsWith(lib_option,argv[idx])) { /* check for -l option */
append(&gstr.pLIB,argv[idx]);
append(&gstr.pLIB," ");
}
else if (startsWith(mingw_option,argv[idx])) /* check for -mingw option */
assignn(&gstr.pMINGW,argv[idx]+sizeof(mingw_option)-1,strlen(argv[idx])-(sizeof(mingw_option)-1));
else if (startsWith(ivl_option,argv[idx])) /* check for -ivl option */
assignn(&gstr.pIVL,argv[idx]+sizeof(ivl_option)-1,strlen(argv[idx])-(sizeof(ivl_option)-1));
else
return 0; /* different from iverilog-vpi.sh, we don't ignore accept arguments */
}
if (0 == srcFileCnt)
assign(&gstr.pOUT,""); /* in case they used --name with no source files */
if (!*gstr.pOUT) { /* normally it's an error if there are no *.c,*.cc,*.o files */
if (!*gstr.pMINGW && !*gstr.pIVL) /* unless they are just setting the IVL or MinGW registry entries */
usage();
}
else {
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
append(&gstr.pOUT," ");
}
return 1;
}
/* do minimal check that the MinGW root directory looks valid */
static void checkMingwDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
initDynString(&path);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\\\mingw\n");
myExit(5);
}
}
/* do minimal check that the Icarus Verilog root directory looks valid */
static void checkIvlDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
initDynString(&path);
assign(&path,gstr.pIVL);
appendBackSlash(&path);
append(&path,"bin\\vvp.exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\\\iverilog\n");
myExit(6);
}
}
/* see if we can find mingw root */
#define IVL_REGKEY_MINGW "MingwDir"
static void setup_mingw_environment()
{
char *pOldPATH = getenv("PATH"); /* get current path */
if (*gstr.pMINGW) {
checkMingwDir(gstr.pMINGW);
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
}
else
if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
fprintf(stderr," a Windows command shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
myExit(5);
}
assign(&gstr.pNewPath,"PATH="); /* create new path */
append(&gstr.pNewPath,gstr.pMINGW);
appendBackSlash(&gstr.pNewPath);
append(&gstr.pNewPath,"bin;");
append(&gstr.pNewPath,pOldPATH);
_putenv(gstr.pNewPath); /* place new path in environment variable */
}
/* see if we can find iverilog root */
#define IVL_REGKEY_IVL "InstallDir"
static void setup_ivl_environment()
{
if (*gstr.pIVL) {
checkIvlDir(gstr.pIVL);
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
}
else
if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
fprintf(stderr," For a Windows command shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
myExit(6);
}
/* build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"include");
/* build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L");
append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS,"lib ");
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
static void compile(char *pSource, char **pObject, char *ext, int *compile_errors, char *compiler)
{
char *ptr1 = pSource;
char *ptr2 = strchr(pSource,' ');
char *buf=0,*src=0,*obj=0;
while (ptr2) {
int len = ptr2 - ptr1;
assignn(&src,ptr1,len);
assignn(&obj,ptr1,len-strlen(ext)); /* strip off the extension */
append (&obj,".o");
assign (&buf,compiler);
append (&buf," -c -o ");
append (&buf,obj);
append (&buf," ");
append (&buf,gstr.pCFLAGS);
append (&buf," ");
append (&buf,src);
append (pObject,obj);
append (pObject," ");
printf("%s\n",buf);
if (system(buf))
++*compile_errors;
ptr1 = ptr2 + 1; /* advance to next token */
ptr2 = strchr(ptr1,' ');
}
free(buf);
free(src);
free(obj);
}
/* using the global strings, compile and link */
static void compile_and_link()
{
char *buf=0;
int iRet, compile_errors = 0;
/* print out the mingw and ivl directories to help the user debug problems */
printf("info: %s will be used as the MinGW root directory.\n",gstr.pMINGW);
checkMingwDir(gstr.pMINGW);
printf("info: %s will be used as the Icarus Verilog root directory.\n",gstr.pIVL);
checkIvlDir(gstr.pIVL);
/* compile */
compile(gstr.pCCSRC,&gstr.pOBJ,".c" ,&compile_errors,IVERILOG_VPI_CC ); /* compile the C source files */
compile(gstr.pCXSRC,&gstr.pOBJ,".cc",&compile_errors,IVERILOG_VPI_CXX); /* compile the C++ source files */
if (compile_errors) {
fprintf(stderr,"iverilog-vpi: Some %d files failed to compile.\n",compile_errors);
myExit(2);
}
/* link */
assign(&buf,IVERILOG_VPI_LD);
append(&buf," -o ");
append(&buf,gstr.pOUT); /* has a trailing space */
append(&buf,IVERILOG_VPI_LDFLAGS);
append(&buf," ");
append(&buf,gstr.pOBJ) /* has a trailing space */;
append(&buf,gstr.pLIB); /* has a trailing space */
append(&buf,gstr.pLDLIBS);
printf("%s\n",buf);
iRet = system(buf);
free(buf);
if (iRet)
myExit(3);
}
/* program execution starts here */
int main(int argc, char *argv[])
{
init();
if (!parse(argc,argv))
usage();
setup_mingw_environment();
setup_ivl_environment();
if (*gstr.pOUT) /* are there any *.c,*.cc,*.o files specified */
compile_and_link();
myExit(0);
}
-38
View File
@@ -1,38 +0,0 @@
// LANGUAGE ENGLISH
LANGUAGE 9, 4
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 2002,11,13,0
PRODUCTVERSION 0,7,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x2L
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Icarus Verilog\0"
VALUE "FileDescription", "Icarus Verilog VPI Tool\0"
VALUE "FileVersion", "2002, 11, 13, 0\0"
VALUE "InternalName", "iverilog-vpi\0"
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
VALUE "ProductName", "Icarus Verilog\0"
VALUE "ProductVersion", "0, 7, 0, 0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
-3
View File
@@ -10,6 +10,3 @@ cfparse.output
cflexor.c
foo.*
iverilog
iverilog.ps
iverilog.pdf
tmp.pdf
+26 -20
View File
@@ -3,7 +3,9 @@
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
# any later version. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,12 +18,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.26 2007/02/06 05:07:31 steve Exp $"
#ident "$Id: Makefile.in,v 1.11 2002/02/03 07:05:36 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.8
VERSION = 0.6
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -35,14 +37,17 @@ includedir = $(prefix)/include
mandir = @mandir@
dllib=@DLLIB@
rdynamic=@rdynamic@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
all: iverilog@EXEEXT@
@@ -50,16 +55,18 @@ all: iverilog@EXEEXT@
clean:
rm -f *.o lexor.c parse.c parse.h parse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
distclean: clean
rm -f Makefile
O = main.o substit.o cflexor.o cfparse.o
O = main.o build_string.o lexor.o parse.o cflexor.o cfparse.o
iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
lexor.c: lexor.lex
flex -s -olexor.c $(srcdir)/lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
cflexor.c: cflexor.lex
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
@@ -68,21 +75,20 @@ cfparse.h cfparse.c: cfparse.y
main.o: main.c globals.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' -DEXEEXT='"@EXEEXT@"' $(srcdir)/main.c
build_string.o: build_string.c globals.h
lexor.o: lexor.c parse.h globals.h
parse.o: parse.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
cfparse.o: cfparse.c globals.h cfparse_misc.h
iverilog.ps: $(srcdir)/iverilog.man
man -t $(srcdir)/iverilog.man > iverilog.ps
iverilog.pdf: $(srcdir)/iverilog.man
man -t $(srcdir)/iverilog.man | ps2pdf - iverilog.pdf
iverilog.pdf: iverilog.ps
ps2pdf iverilog.ps iverilog.pdf
ifeq (@MING32@,yes)
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
INSTALL_DOCDIR = $(mandir)/man1
ifeq (@WIN32@,yes)
INSTALL_DOC = $(prefix)/iverilog.pdf
INSTALL_DOCDIR =
all: iverilog.pdf
else
INSTALL_DOC = $(mandir)/man1/iverilog.1
@@ -105,4 +111,4 @@ installdirs: ../mkinstalldirs
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf
rm -f $(mandir)/man1/iverilog.1
+183
View File
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2000 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: build_string.c,v 1.6 2001/11/16 05:07:19 steve Exp $"
#endif
# include "config.h"
# include "globals.h"
# include <string.h>
# include <assert.h>
int build_string(char*output, size_t olen, const char*pattern)
{
char tmp_buf[1024];
char*output_save = output;
while (*pattern) {
if (*pattern == '%') {
pattern += 1;
switch (*pattern) {
case 0:
break;
case '%':
*output++ = '%';
break;
case '[': {
const char*tail;
pattern += 1;
assert(*pattern);
tail = strchr(pattern+1, ']');
assert(tail);
strncpy(tmp_buf, pattern+1, tail-pattern-1);
tmp_buf[tail-pattern-1] = 0;
if (((*pattern == 's') && start)
|| ((*pattern == 'v') && verbose_flag)
|| ((*pattern == 'N') && npath)
|| ((*pattern == 'T') && mtm)) {
int rc = build_string(output, olen,
tmp_buf);
output += rc;
olen -= rc;
}
pattern = tail;
break;
}
case 'B':
strcpy(output, base);
output += strlen(base);
olen -= strlen(base);
break;
case 'f':
if (f_list) {
strcpy(output, f_list);
output += strlen(f_list);
olen -= strlen(f_list);
}
break;
case 'm':
if (mod_list) {
strcpy(output, mod_list);
output += strlen(mod_list);
olen -= strlen(mod_list);
}
break;
case 'N':
if (npath) {
strcpy(output, npath);
output += strlen(npath);
olen -= strlen(npath);
}
break;
case 'o':
strcpy(output, opath);
output += strlen(opath);
olen -= strlen(opath);
break;
case 's':
if (start) {
strcpy(output, start);
output += strlen(start);
olen -= strlen(start);
}
break;
case 'T':
if (mtm) {
strcpy(output, mtm);
output += strlen(mtm);
olen -= strlen(mtm);
}
break;
case 't':
strcpy(output, targ);
output += strlen(targ);
olen -= strlen(targ);
break;
case 'W':
strcpy(output, warning_flags);
output += strlen(warning_flags);
olen -= strlen(warning_flags);
break;
case 'y':
if (library_flags) {
strcpy(output, library_flags);
output += strlen(library_flags);
olen -= strlen(library_flags);
}
break;
case 'Y':
if (library_flags2) {
strcpy(output, library_flags2);
output += strlen(library_flags2);
olen -= strlen(library_flags2);
}
break;
}
pattern += 1;
} else {
*output++ = *pattern++;
olen -= 1;
}
}
*output = 0;
return output-output_save;
}
/*
* $Log: build_string.c,v $
* Revision 1.6 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.4 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.3 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.2 2000/10/28 03:45:47 steve
* Use the conf file to generate the vvm ivl string.
*
* Revision 1.1 2000/10/08 22:36:56 steve
* iverilog with an iverilog.conf configuration file.
*
*/
+7 -47
View File
@@ -18,8 +18,8 @@
* 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: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $"
#endif
# include "cfparse.h"
@@ -37,14 +37,12 @@
YYLTYPE yylloc;
static int comment_enter;
static char* trim_trailing_white(char*txt, int trim);
%}
%x CCOMMENT
%x LCOMMENT
%x PLUS_ARGS
%x FILE_NAME
%%
@@ -72,13 +70,8 @@ static int comment_enter;
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
@@ -115,50 +108,17 @@ static int comment_enter;
/* This rule matches paths and strings that may be file names. This
is a little bit tricky, as we don't want to mistake a comment for
a string word. */
"/"[\r\n] { /* Special case of file name "/" */
cflval.text = trim_trailing_white(yytext, 0);
return TOK_STRING; }
"/"[^\*\/] { /* A file name that starts with "/". */
yymore();
BEGIN(FILE_NAME); }
[^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */
yymore();
BEGIN(FILE_NAME); }
"/"[^\*\/].* { cflval.text = strdup(yytext);
return TOK_STRING; }
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
return TOK_STRING; }
<FILE_NAME>"//" {
/* Found a trailing comment. Returning the terminated name. */
cflval.text = trim_trailing_white(yytext, 2);
BEGIN(LCOMMENT);
return TOK_STRING; }
<FILE_NAME>"/"?[^/\n\r]* {
yymore();
/* not a comment... continuing */; }
<FILE_NAME>[\n\r] {
/* No trailing comment. Return the file name. */
cflval.text = trim_trailing_white(yytext, 0);
BEGIN(0);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
%%
static char* trim_trailing_white(char*text, int trim)
{
char*cp = text + strlen(text);
while (cp > text && trim > 0) {
trim -= 1;
cp -= 1;
*cp = 0;
}
while (cp > text && strchr("\n\r\t\b", cp[-1]))
cp -= 1;
cp[0] = 0;
return strdup(text);
}
int yywrap()
{
return 1;
+11 -45
View File
@@ -17,17 +17,14 @@
* 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: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cfparse.y,v 1.6 2002/01/02 02:39:34 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
# include <ctype.h>
# include <stdlib.h>
# include <string.h>
/*
* This flag is set to 0, 1 or 2 if file names are to be translated to
@@ -61,8 +58,7 @@ static void translate_file_name(char*text)
};
%token TOK_Da TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -82,11 +78,9 @@ item
of a source file. Add the file to the file list. */
: TOK_STRING
{ char*tmp = substitutions($1);
translate_file_name(tmp);
process_file_name(tmp, 0);
{ translate_file_name($1);
process_file_name($1);
free($1);
free(tmp);
}
/* The -a flag is completely ignored. */
@@ -97,11 +91,11 @@ item
as an ordinary source file. */
| TOK_Dv TOK_STRING
{ char*tmp = substitutions($2);
translate_file_name(tmp);
process_file_name(tmp, 1);
{ translate_file_name($2);
process_file_name($2);
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
@1.text, @1.first_line, $2);
free($2);
free(tmp);
}
/* This rule matches "-y <path>" sequences. This does the same thing
@@ -109,24 +103,8 @@ item
directory list. */
| TOK_Dy TOK_STRING
{ char*tmp = substitutions($2);
process_library_switch(tmp);
{ process_library_switch($2);
free($2);
free(tmp);
}
| TOK_LIBDIR TOK_PLUSARG
{ char*tmp = substitutions($2);
process_library_switch(tmp);
free($2);
free(tmp);
}
| TOK_LIBDIR_NOCASE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_library_nocase_switch(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
@@ -144,15 +122,6 @@ item
| TOK_LIBEXT libext_args
/* These are various misc flags that are supported. */
| TOK_INTEGER_WIDTH TOK_PLUSARG
{ char*tmp = substitutions($2);
free($2);
integer_width = strtoul(tmp,0,10);
free(tmp);
}
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
@@ -182,10 +151,8 @@ inc_args
;
inc_arg : TOK_PLUSARG
{ char*tmp = substitutions($1);
process_include_dir(tmp);
{ process_include_dir($1);
free($1);
free(tmp);
}
;
@@ -218,5 +185,4 @@ skip_arg : TOK_PLUSARG
int yyerror(const char*msg)
{
return 0;
}
+2 -15
View File
@@ -19,8 +19,8 @@
* 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: cfparse_misc.h,v 1.6 2004/02/15 18:03:30 steve Exp $"
#if !defined(WINNT)
#ident "$Id: cfparse_misc.h,v 1.3 2002/01/02 02:39:34 steve Exp $"
#endif
/*
@@ -38,21 +38,8 @@ struct cfltype {
# define YYLTYPE struct cfltype
extern YYLTYPE yylloc;
int cflex(void);
int cferror(const char *);
int cfparse(void);
/*
* $Log: cfparse_misc.h,v $
* Revision 1.6 2004/02/15 18:03:30 steve
* Cleanup of warnings.
*
* Revision 1.5 2003/09/26 21:25:58 steve
* Warnings cleanup.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/02 02:39:34 steve
* Use my own cfltype to defend against bison 1.30.
*
+38 -36
View File
@@ -18,8 +18,8 @@
* 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: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: globals.h,v 1.10 2001/11/16 05:07:19 steve Exp $"
#endif
# include <stddef.h>
@@ -27,12 +27,14 @@
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is the path to the iconfig file sent to ivl. */
extern char* iconfig_path;
extern char* iconfig_common_path;
/* This is a list of all the -f<key>=<value> options from the
command line, concatenated together. */
extern char*f_list;
/* Ths is the optional -M<dependfile> value, if one was supplied. */
extern const char*depfile;
extern char*mod_list;
/* This is the optional -Tmin|typ|max setting. */
extern const char*mtm;
/* Ths is the optional -N<path> value, if one was supplied. */
extern const char*npath;
@@ -49,18 +51,11 @@ extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width;
/* Perform variable substitutions on the string. */
extern char* substitutions(const char*str);
/* Add the name to the list of source files. */
extern void process_file_name(const char*name, int lib_flag);
extern void process_file_name(const char*name);
/* Add the name to the list of library directories. */
extern void process_library_switch(const char*name);
extern void process_library_nocase_switch(const char*name);
extern void process_library2_switch(const char*name);
/* Add a new include file search directory */
@@ -78,36 +73,43 @@ extern char warning_flags[];
extern char* library_flags;
extern char* library_flags2;
extern const char*lookup_pattern(const char*key);
extern int build_string(char*out, size_t olen, const char*pattern);
/*
* $Log: globals.h,v $
* Revision 1.21 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
* Revision 1.10 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.20 2007/03/07 04:24:59 steve
* Make integer width controllable.
* Revision 1.9 2001/11/13 03:30:26 steve
* The +incdir+ plusarg can take multiple directores,
* and add initial support for +define+ in the command file.
*
* Revision 1.19 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
* Revision 1.8 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.18 2003/11/13 04:09:49 steve
* Pass flags through the temporary config file.
* Revision 1.7 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
* Revision 1.17 2003/11/01 04:21:57 steve
* Add support for a target static config file.
* Revision 1.6 2001/10/23 00:37:30 steve
* The -s flag can now be repeated on the iverilog command.
*
* Revision 1.16 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.15 2002/06/23 20:10:51 steve
* Variable substitution in command files.
* Revision 1.4 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.14 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
* Revision 1.3 2000/11/09 21:58:00 steve
* Remember to include the -S condition.
*
* Revision 1.2 2000/10/28 03:45:47 steve
* Use the conf file to generate the vvm ivl string.
*
* Revision 1.1 2000/10/08 22:36:56 steve
* iverilog with an iverilog.conf configuration file.
*
* Revision 1.13 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*/
#endif
+29 -138
View File
@@ -1,12 +1,12 @@
.TH iverilog 1 "$Date: 2007/06/05 01:56:12 $" Version "$Date: 2007/06/05 01:56:12 $"
.TH iverilog 1 "$Date: 2002/02/16 03:18:54 $" Version "$Date: 2002/02/16 03:18:54 $"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g2x|-gspecify-gxtypes] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
[-ESVv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
.SH DESCRIPTION
.PP
@@ -21,12 +21,11 @@ types are added as code generators are implemented.
\fIiverilog\fP accepts the following options:
.TP 8
.B -B\fIbase\fP
The \fIiverilog\fP program uses external programs and configuration
files to preprocess and compile the Verilog source. Normally, the path
used to locate these tools is built into the \fIiverilog\fP
program. However, the \fB-B\fP switch allows the user to select a
different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
The \fIiverilog\fP program uses external programs to preprocess and
compile the Verilog source. Normally, the path used to locate these
tools is built into the \fIiverilog\fP program. However, the \fB-B\fP
switch allows the user to select a different set of programs. The path
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
.TP 8
.B -c\fIfile\fP
This flag specifies an input file that contains a list of Verilog
@@ -34,6 +33,14 @@ source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. See \fBCommand Files\fP below.
.TP 8
.B -C\fIpath\fP
This flag selects the driver configuration file to use. Normally, the
iverilog program will read its configuration file from
/usr/lib/ivl/iverilog.conf (or the install path configured at compile
time) but the user can specify the path to a different configuration
file. This is useful when testing new configuration files. See the
installed configuration file for a summary of the file format.
.TP 8
.B -D\fImacro\fP
Defines macro \fImacro\fP with the string `1' as its definition. This
form is normally only used to trigger ifdef conditionals in the
@@ -48,49 +55,16 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1\fI|\fP-g2\fI|\fP-g2x
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP(1),
\fIIEEE1364-2001\fP(2), or \fIVerilog with extension\fP(2x). Normally,
Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -gspecify\fI|\fP-gno-specify
Enable (default) or disable specify block support. When enabled,
specify block code is elaborated. When disabled, specify blocks are
parsed but ignored. Specify blocks are commonly not needed for RTL
simulation, and in fact can hurt performance of the
simulation. However, disabling specify blocks reduces accuracy of
full-timing simulations.
.TP 8
.B -gxtypes\fI|\fP-gno-xtypes
Enable (default) or disable support for extended types. Enabling
extended types allows for new types that are supported by Icarus
Verilog as extensions beyond the baseline Verilog. It may be necessary
to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system.
.TP 8
.B -I\fIincludedir\fP
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -M\fIpath\fP
Write into the file specified by path a list of files that contribute
to the compilation of the design. This includes files that are
included by include directives and files that are automatically loaded
by library support. The output is one file name per line, with no
leading or trailing space.
.TP 8
.B -m\fImodule\fP
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
@@ -137,11 +111,7 @@ Use this switch to specify the target output format. See the
Turn on verbose messages. This will print the command lines that are
executed to perform the actual compilation, along with version
information from the various components, as well as the version of the
product as a whole. You will notice that the command lines include
a reference to a key temporary file that passes information to the
compiler proper. To keep that file from being deleted at the end
of the process, provide a file name of your own in the environment
variable \fBIVERILOG_ICONFIG\fP.
product as a whole.
.TP 8
.B -V
Print the version of the compiler, and exit.
@@ -189,21 +159,18 @@ but must be run by the \fBvvp\fP command.
.TP 8
.B xnf
This is the Xilinx Netlist Format used by many tools for placing
devices in FPGAs or other programmable devices. This target is
obsolete, use the \fBfpga\fP target instead.
devices in FPGAs or other programmable devices. The Icarus Verilog XNF
code generator can generate complete designs or XNF macros that can be
imported into larger designs by other tools. (This target is obsolete,
use the \fBfpga\fP target instead.)
.TP 8
.B fpga
This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output. The Icarus Verilog fpga code generator
can generate complete designs or EDIF macros that can in turn be
imported into larger designs by other tools. The \fBfpga\fP target
implies the synthesis \fB-S\fP flag.
mostly by EDIF format output.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB-W\fP
switch. All the warning types (other than \fBall\fP) can also be
prefixed with \fBno-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types.
switch.
.TP 8
.B all
@@ -215,47 +182,6 @@ This enables warnings for creation of implicit declarations. For
example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use.
.TP 8
.B portbind
This enables warnings for ports of module instantiations that are not
connected but probably should be. Dangling input ports, for example,
will generate a warning.
.TP 8
.B timescale
This enables warnings for inconsistent use of the timescale
directive. It detects if some modules have no timescale, or if modules
inherit timescale from another file. Both probably mean that
timescales are inconsistent, and simulation timing can be confusing
and dependent on compilation order.
.SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be
a system function table file. A System function table file is used to
describe to the compiler the return types for system functions. This
is necessary because the compiler needs this information to elaborate
expressions that contain these system functions, but cannot run the
sizetf functions since it has no run-time.
The format of the table is ASCII, one function per line. Empty lines
are ignored, and lines that start with the '\fI#\fP' character are
comment lines. Each non-comment line starts with the function name,
then the vpi type (i.e. vpiSysFuncReal). The following types are
supported:
.TP 8
.B vpiSysFuncReal
The function returns a real/realtime value.
.TP 8
.B vpiSysFuncInt
The function returns an integer.
.TP 8
.B vpiSysFuncSized <wid> <signed|unsigned>
The function returns a vector with the given width, and is signed or
unsigned according to the flag.
.SH "COMMAND FILES"
The command file allows the user to place source file names and
certain command line switches into a text file instead of on a long
@@ -265,8 +191,7 @@ well as # comments, if the # starts the line.
.TP 8
.I "file name"
A simple file name or file path is taken to be the name of a Verilog
source file. The path starts with the first non-white-space
character. Variables are substituted in file names.
source file. The path starts with the first non-white-space character.
.TP 8
.B -y\ \fIlibdir\fP
@@ -274,8 +199,6 @@ A \fB-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB-y\fP
flag may be on the same line or the next non-comment line.
Variables in the \fIlibdir\fP are substituted.
.TP 8
.B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search
@@ -284,8 +207,6 @@ command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines.
Variables in the \fIincludedir\fP are substituted.
.TP 8
.B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try
@@ -293,18 +214,6 @@ when looking for a library file. This is useful in conjunction with
\fB-y\fP flags to list suffixes to try in each directory before moving
on to the next library directory.
.TP 8
.B +libdir+\fIdir\fP
This is another way to specify library directories. See the -y flag.
.TP 8
.B +libdir-nocase+\fIdir\fP
This is like the \fB+libdir\fP statement, but file names inside the
directories declared here are case insensitive. The missing module
name in a lookup need not match the file name case, as long as the
letters are correct. For example, "foo" matches "Foo.v" but not
"bar.v".
.TP 8
.B +define+\fINAME\fP=\fIvalue\fP
The \fB+define+\fP token is the same as the \fB-D\fP option on the
@@ -321,25 +230,7 @@ become munged.
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.TP 8
.B +integer-width+\fIvalue\fP
This allows the programmer to select the width for integer variables
in the Verilog source. The default is 32, the value can be any desired
integer value.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substituted in contexts that explicitly support them, including file
and directory strings.
Variable values come from the operating system environment, and not
from preprocessor defines elsewhere in the file or the command line.
.SH EXAMPLES
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
the current directory
@@ -370,7 +261,7 @@ vvp(1),
.SH COPYRIGHT
.nf
Copyright \(co 2002 Stephen Williams
Copyright \(co 2000 Stephen Williams
This document can be freely redistributed according to the terms of the
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+80
View File
@@ -0,0 +1,80 @@
%{
/*
* Copyright (c) 2000 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.5 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
# include <string.h>
# include "parse.h"
%}
%x CTOKENS
%x PATTERN
%%
"#".* { /* eat comments */; }
"\n" { /* eat line-ends */; }
"\r" { /* eat line-ends */; }
"[" { BEGIN(CTOKENS); return '['; }
<CTOKENS>"]" { BEGIN(0); return ']'; }
<CTOKENS>[ \t\b]+ { /* skip white space */; }
<CTOKENS>"-S" { return CT_S; }
<CTOKENS>"-t"[a-zA-Z0-9\-_]+ {
yylval.text = strdup(yytext+2);
return CT_t; }
"<"[^>]*">" {
BEGIN(PATTERN);
yylval.text = strdup(yytext);
return PATTERN_NAME; }
<PATTERN>.* {
BEGIN(0);
/* Trim off a trailing \r. This is an issue in the DOS world. */
if (yytext[strlen(yytext)-1] == '\r')
yytext[strlen(yytext)-1] = 0;
yylval.text = strdup(yytext);
return PATTERN_TEXT; }
. { fprintf(stderr, "driver lexor: Unmatched character: %c\n", yytext[0]); }
%%
void reset_lexor(FILE*fd)
{
yyrestart(fd);
}
int yywrap()
{
return 1;
}
+316 -475
View File
File diff suppressed because it is too large Load Diff
+167
View File
@@ -0,0 +1,167 @@
%{
/*
* Copyright (c) 2000 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.4 2001/09/15 18:27:04 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include "globals.h"
void yyerror(const char*);
enum drive_code_t {
CODE_S,
CODE_t,
};
struct drive_cond {
struct drive_cond*next;
enum drive_code_t code;
char* text;
};
static struct drive_cond *cur_cond = 0;
static void add_cond(enum drive_code_t code, char*text)
{
struct drive_cond*tmp;
tmp = calloc(1, sizeof(struct drive_cond));
tmp->code = code;
tmp->text = text;
tmp->next = cur_cond;
cur_cond = tmp;
}
struct drive_pattern {
struct drive_pattern*next;
char*name;
char*text;
struct drive_cond*cond;
};
static struct drive_pattern *patterns = 0;
static struct drive_pattern *plast = 0;
static void add_pattern(char*name, char*text)
{
struct drive_pattern*tmp;
tmp = calloc(1, sizeof(struct drive_pattern));
tmp->name = name;
tmp->text = text;
tmp->cond = cur_cond;
tmp->next = 0;
if (plast) {
plast->next = tmp;
plast = tmp;
} else {
patterns = tmp;
plast = tmp;
}
}
const char*lookup_pattern(const char*key)
{
struct drive_pattern*cur;
struct drive_cond*cc;
for (cur = patterns ; cur ; cur = cur->next) {
if (strcmp(key, cur->name) != 0)
continue;
for (cc = cur->cond ; cc ; cc = cc->next) {
switch (cc->code) {
case CODE_S:
if (synth_flag)
continue;
break;
case CODE_t:
if (strcmp(targ, cc->text) == 0)
continue;
break;
}
break;
}
if (cc) continue;
return cur->text;
}
return 0;
}
%}
%union {
char*text;
};
%token <text> PATTERN_NAME PATTERN_TEXT
%token <text> CT_t
%token CT_S
%%
start: section_list
section_list
: section
| section_list section
;
section : '[' ctoken_list ']' pattern_list { cur_cond = 0; } ;
ctoken_list
: ctoken
| ctoken_list ctoken
;
ctoken : CT_S { add_cond(CODE_S, 0); }
| CT_t { add_cond(CODE_t, $1); }
;
pattern_list
: pattern
| pattern_list pattern
;
pattern : PATTERN_NAME PATTERN_TEXT
{ add_pattern($1, $2); }
;
%%
void yyerror(const char*msg)
{
fprintf(stderr, "%s\n", msg);
}
-115
View File
@@ -1,115 +0,0 @@
/*
* Copyright (c) 2002 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
* 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: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
char* substitutions(const char*str)
{
size_t nbuf = strlen(str) + 1;
char*buf = malloc(nbuf);
char*cp = buf;
while (*str) {
if ((str[0] == '$') && (str[1] == '(')) {
/* If I find a $(x) string in the source, replace
it in the destination with the contents of the
environment variable x. */
char*name;
char*value;
const char*ep = strchr(str, ')');
str += 2;
name = malloc(ep-str+1);
strncpy(name, str, ep-str);
name[ep-str] = 0;
str = ep + 1;
value = getenv(name);
free(name);
if (value == 0)
continue;
if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf;
nbuf = (cp - buf) + strlen(value) + 1;
buf = realloc(buf, nbuf);
cp = buf + old_size;
}
strcpy(cp, value);
cp += strlen(cp);
} else {
if ( cp == (buf + nbuf) ) {
size_t old_size = nbuf;
nbuf = old_size + 32;
buf = realloc(buf, nbuf);
cp = buf + old_size;
}
*cp++ = *str++;
}
}
/* Add the trailing nul to the string, and reallocate the
buffer to be a tight fit. */
if ( cp == (buf + nbuf) ) {
size_t old_size = nbuf;
nbuf = old_size + 1;
buf = realloc(buf, nbuf);
buf[old_size] = 0;
} else {
*cp++ = 0;
nbuf = cp - buf;
buf = realloc(buf, nbuf);
}
return buf;
}
/*
* $Log: substit.c,v $
* Revision 1.5 2003/12/19 01:27:10 steve
* Fix various unsigned compare warnings.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/
+13 -115
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
* Copyright (c) 1999 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
@@ -16,8 +16,8 @@
* 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: dup_expr.cc,v 1.21 2006/11/04 06:10:13 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: dup_expr.cc,v 1.7 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -25,40 +25,6 @@
# include "netlist.h"
# include <cassert>
NetEBComp* NetEBComp::dup_expr() const
{
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEConst* NetEConst::dup_expr() const
{
NetEConst*tmp = new NetEConst(value_);
tmp->set_line(*this);
return tmp;
}
NetEConstParam* NetEConstParam::dup_expr() const
{
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
tmp->set_line(*this);
return tmp;
}
NetECRealParam* NetECRealParam::dup_expr() const
{
NetECRealParam*tmp = new NetECRealParam(scope_, name_, value());
tmp->set_line(*this);
return tmp;
}
NetEEvent* NetEEvent::dup_expr() const
{
assert(0);
return 0;
}
NetEScope* NetEScope::dup_expr() const
{
assert(0);
@@ -67,17 +33,14 @@ NetEScope* NetEScope::dup_expr() const
NetESelect* NetESelect::dup_expr() const
{
return new NetESelect(expr_->dup_expr(),
base_? base_->dup_expr() : 0,
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
expr_width());
}
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
assert(tmp);
tmp->cast_signed(has_sign());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
assert(tmp->parm(idx));
tmp->parm(idx, tmp->parm(idx)->dup_expr());
@@ -88,7 +51,7 @@ NetESFunc* NetESFunc::dup_expr() const
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_);
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
assert(tmp);
tmp->expr_width(expr_width());
return tmp;
@@ -102,22 +65,6 @@ NetETernary* NetETernary::dup_expr() const
return tmp;
}
NetEUFunc* NetEUFunc::dup_expr() const
{
NetEUFunc*tmp;
svector<NetExpr*> tmp_parms (parms_.count());
for (unsigned idx = 0 ; idx < tmp_parms.count() ; idx += 1) {
assert(parms_[idx]);
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
assert(tmp);
return tmp;
}
NetEUnary* NetEUnary::dup_expr() const
{
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
@@ -125,64 +72,8 @@ NetEUnary* NetEUnary::dup_expr() const
return tmp;
}
NetEUReduce* NetEUReduce::dup_expr() const
{
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
assert(tmp);
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* Revision 1.21 2006/11/04 06:10:13 steve
* Handle dup of pad as well as normal select.
*
* Revision 1.20 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.19 2004/12/11 02:31:25 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.18 2004/06/17 16:06:18 steve
* Help system function signedness survive elaboration.
*
* Revision 1.17 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.16 2003/10/31 02:47:11 steve
* NetEUReduce has its own dup_expr method.
*
* Revision 1.15 2003/05/30 02:55:32 steve
* Support parameters in real expressions and
* as real expressions, and fix multiply and
* divide with real results.
*
* Revision 1.14 2003/04/22 04:48:29 steve
* Support event names as expressions elements.
*
* Revision 1.13 2003/03/15 18:08:43 steve
* Comparison operators do have defined width.
*
* Revision 1.12 2003/03/15 04:46:28 steve
* Better organize the NetESFunc return type guesses.
*
* Revision 1.11 2003/03/10 23:40:53 steve
* Keep parameter constants for the ivl_target API.
*
* Revision 1.10 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.9 2002/11/09 00:25:27 steve
* Add dup_expr for user defined function calls.
*
* Revision 1.8 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.7 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
@@ -203,5 +94,12 @@ NetEUReduce* NetEUReduce::dup_expr() const
* Revision 1.3 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
*/
+17 -64
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003 Stephen Williams ([email protected])
* Copyright (c) 2000 Stephen Williams ([email protected].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
@@ -16,8 +16,8 @@
* 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: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
@@ -29,13 +29,12 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include <iostream>
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
{
cerr << get_line() << ": error: Invalid expression on left side "
<< "of procedural continuous assignment." << endl;
<< "of precedural continuous asignment." << endl;
return 0;
}
@@ -84,18 +83,15 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
concat operator from least significant to most significant,
which is opposite from how they are given in the list.
Allow for a repeat count other than 1 by repeating the
Allow for a repeat count other then 1 by repeating the
connect loop as many times as necessary. */
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
NetNet::IMPLICIT_REG, pins);
/* Assume that all the data types are the same. */
osig->data_type(nets[0]->data_type());
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
assert(cur->data_type() == osig->data_type());
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
@@ -108,33 +104,17 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
{
assert(scope);
NetNet* sig = 0;
NetMemory* mem = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, sig, mem, par, eve);
if (mem != 0) {
cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous "
<< "assignment." << endl;
des->errors += 1;
return 0;
}
if (eve != 0) {
cerr << get_line() << ": error: named events not allowed "
<< "on left side of procedural continuous "
<< "assignment." << endl;
des->errors += 1;
return 0;
}
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
if (NetMemory*mem = des->find_memory(scope, path_)) {
cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous "
<< "asignment." << endl;
des->errors += 1;
return 0;
}
cerr << get_line() << ": error: reg ``" << path_ << "'' "
<< "is undefined in this scope." << endl;
des->errors += 1;
@@ -158,8 +138,8 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
if (msb_ || lsb_) {
cerr << get_line() << ": error: bit/part selects not allowed "
<< "on left side of procedural continuous assignment."
<< endl;
<< "on left side of procedural continuous asignment."
<< endl;
des->errors += 1;
return 0;
}
@@ -169,33 +149,6 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/*
* $Log: elab_anet.cc,v $
* Revision 1.13 2007/03/22 16:08:14 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/05/01 20:47:58 steve
* More explicit datatype setup.
*
* Revision 1.11 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.10 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2003/09/19 03:50:12 steve
* Remove find_memory method from Design class.
*
* Revision 1.8 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.7 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+299 -1511
View File
File diff suppressed because it is too large Load Diff
+122 -354
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2006 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000 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
@@ -16,38 +16,36 @@
* 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: elab_lval.cc,v 1.44 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_lval.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
# include <iostream>
# include "ivl_assert.h"
/*
* These methods generate a NetAssign_ object for the l-value of the
* assignment. This is common code for the = and <= statements.
* assignemnt. This is common code for the = and <= statements.
*
* What gets generated depends on the structure of the l-value. If the
* l-value is a simple name (i.e., foo <= <value>) the the NetAssign_
* l-value is a simple name (i.e. foo <= <value>) the the NetAssign_
* is created the width of the foo reg and connected to all the
* bits.
*
* If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
* If there is a part select (i.e. foo[3:1] <= <value>) the NetAssign_
* is made only as wide as it needs to be (3 bits in this example) and
* connected to the correct bits of foo. A constant bit select is a
* special case of the part select.
* special case of the part select.
*
* If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
* If the bit-select is non-constant (i.e. foo[<expr>] = <value>) the
* NetAssign_ is made wide enough to connect to all the bits of foo,
* then the mux expression is elaborated and attached to the
* NetAssign_ node as a b_mux value. The target must interpret the
* presence of a bmux value as taking a single bit and assigning it to
* presense of a bmux value as taking a single bit and assigning it to
* the bit selected by the bmux expression.
*
* If the l-value expression is non-trivial, but can be fully
@@ -57,7 +55,7 @@
* l-value.
*
* This last case can turn up in statements like: {a, b[1]} = c;
* rather then create a NetAssign_ for each item in the concatenation,
* rather then create a NetAssign_ for each item in the contatenation,
* elaboration makes a single NetAssign_ and connects it up properly.
*/
@@ -67,11 +65,9 @@
* is to try to make a net elaboration, and see if the result is
* suitable for assignment.
*/
NetAssign_* PExpr::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet*ll = 0;
NetNet*ll = elaborate_net(des, scope, 0, 0, 0, 0);
if (ll == 0) {
cerr << get_line() << ": Assignment l-value too complex."
<< endl;
@@ -95,9 +91,7 @@ NetAssign_* PExpr::elaborate_lval(Design*des,
* a is the MSB and b the LSB. Connect the LSB to the low pins of the
* NetAssign_ object.
*/
NetAssign_* PEConcat::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
{
if (repeat_) {
cerr << get_line() << ": error: Repeat concatenations make "
@@ -109,15 +103,7 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*res = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_line() << ": error: Empty expressions "
<< "not allowed in concatenations." << endl;
des->errors += 1;
continue;
}
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
@@ -145,71 +131,31 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
* Handle the ident as an l-value. This includes bit and part selects
* of that ident.
*/
NetAssign_* PEIdent::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet* reg = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, reg, par, eve);
if (reg == 0) {
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
"''" << endl;
des->errors += 1;
return 0;
}
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 && name_tail.index.empty()) {
cerr << get_line() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
des->errors += 1;
return 0;
}
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
return lv;
}
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 (use_sel == index_component_t::SEL_IDX_DO) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
it is a register. (Wires are not allows in this context. */
NetNet*reg = des->find_signal(scope, path_);
if (reg == 0) {
NetMemory*mem = des->find_memory(scope, path_);
if (mem != 0) {
cerr << get_line() << ": sorry: I cannot handle "
<< "memories in this l-value context." << endl;
} else {
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
"''" << endl;
}
des->errors += 1;
return 0;
}
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
@@ -217,29 +163,53 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
long msb, lsb;
NetExpr*mux;
if (use_sel == index_component_t::SEL_BIT) {
if (msb_ && 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. */
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *lsb_;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope);
if (vl == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *msb_;
des->errors += 1;
return 0;
}
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
msb = vm->as_long();
lsb = vl->as_long();
mux = 0;
} else if (msb_) {
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
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();
lsb = index_con->value().as_long();
mux = 0;
} else {
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope);
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
msb = 0;
lsb = 0;
mux = index_expr;
mux = m;
} else {
msb = v->as_long();
lsb = v->as_long();
mux = 0;
}
} else {
@@ -247,6 +217,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
/* No select expressions, so presume a part select the
width of the register. */
assert(msb_ == 0);
assert(lsb_ == 0);
msb = reg->msb();
lsb = reg->lsb();
mux = 0;
@@ -261,19 +233,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
bmux to select the target bit. */
lv = new NetAssign_(reg);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
mux = make_sub_expr(reg->lsb(), mux);
else if (reg->lsb() != 0)
mux = make_add_expr(mux, - reg->lsb());
lv->set_part(mux, 1);
} else if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
lv = new NetAssign_(reg);
lv->set_bmux(mux);
} else {
@@ -297,7 +257,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->vector_width()) {
if ((wid + loff) > reg->pin_count()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
@@ -306,267 +266,75 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
}
lv = new NetAssign_(reg);
lv->set_part(new NetEConst(verinum(loff)), wid);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
}
return lv;
}
NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
NetScope*scope,
NetNet*reg) const
{
const name_component_t&name_tail = path_.back();
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);
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.
if (long base = reg->array_first()) {
word = make_add_expr(word, 0-base);
if (NetExpr*tmp = word->eval_tree()) {
word = tmp;
}
}
NetAssign_*lv = new NetAssign_(reg);
lv->set_word(word);
if (debug_elaborate)
cerr << get_line() << ": debug: Set array word=" << *word << endl;
// Test for the case that the index is a constant, and is out
// of bounds. The "word" expression is the word index already
// converted to canonical address, so this just needs to check
// that the address is not too big.
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
verinum word_val = word_const->value();
long index = word_val.as_long();
if (index < 0 || index >= reg->array_count()) {
cerr << get_line() << ": warning: Constant array index "
<< (index + reg->array_first())
<< " is out of range for array "
<< reg->name() << "." << endl;
}
}
/* An array word may also have part selects applied to them. */
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 (use_sel == index_component_t::SEL_IDX_UP)
elaborate_lval_net_idx_up_(des, scope, lv);
if (use_sel == index_component_t::SEL_IDX_DO)
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
}
bool PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
long msb, lsb;
bool flag = calculate_parts_(des, scope, msb, lsb);
if (!flag)
return false;
NetNet*reg = lv->sig();
assert(reg);
if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
} else {
/* If the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return false;
}
/* If the part select extends beyond the extreme of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->vector_width()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return false;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
}
return true;
}
bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
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_path(scope) <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return false;
}
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
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())
base = make_sub_expr(reg->lsb(), base);
else if (reg->lsb() != 0)
base = make_add_expr(base, - reg->lsb());
if (debug_elaborate)
cerr << get_line() << ": debug: Set part select width="
<< wid << ", base=" << *base << endl;
lv->set_part(base, wid);
return true;
}
bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
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;
return false;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
{
cerr << get_line() << ": error: Constant values not allowed "
<< "in l-value expressions." << endl;
des->errors += 1;
return 0;
}
/*
* $Log: elab_lval.cc,v $
* Revision 1.44 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* 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.16 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.42 2007/03/14 05:06:49 steve
* Replace some asserts with ivl_asserts.
* Revision 1.15 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.41 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
* Revision 1.14 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Revision 1.40 2007/02/27 05:14:38 steve
* Detect and warn about lval array index out fo bounds.
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.39 2007/02/01 05:25:26 steve
* Error message better reflects more general reality.
* Revision 1.13 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.38 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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
* Revision 1.12 2001/02/09 03:16:48 steve
* Report bit/part select out of range errors. (PR#133)
*
* Revision 1.37 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
* contain unsized numbers.
* Revision 1.11 2001/01/10 03:13:23 steve
* Build task outputs as lval instead of nets. (PR#98)
*
* Revision 1.36 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
* Revision 1.10 2001/01/06 06:31:58 steve
* declaration initialization for time variables.
*
* Revision 1.35 2006/04/16 00:54:04 steve
* Cleanup lval part select handling.
* Revision 1.9 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.34 2006/04/16 00:15:43 steve
* Fix part selects in l-values.
* Revision 1.8 2000/12/12 06:14:51 steve
* sorry for concatenated memories in l-values. (PR#76)
*
* Revision 1.33 2006/02/02 02:43:57 steve
* Allow part selects of memory words in l-values.
* Revision 1.7 2000/12/01 02:55:37 steve
* Detect part select errors on l-values.
*
* Revision 1.32 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
* Revision 1.6 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.31 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
* Revision 1.5 2000/10/26 17:09:46 steve
* Fix handling of errors in behavioral lvalues. (PR#28)
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
* Revision 1.4 2000/09/10 15:43:59 steve
* Some error checking.
*
* Revision 1.30 2004/12/11 02:31:25 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.3 2000/09/10 03:59:59 steve
* Agressively merge NetAssign_ within concatenations.
*
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
* Revision 1.2 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.28 2004/08/28 14:59:44 steve
* More detailed error message about bad variable.
* Revision 1.1 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
* Revision 1.27 2003/09/19 03:30:05 steve
* Fix name search in elab_lval.
*/
+984 -2213
View File
File diff suppressed because it is too large Load Diff
+39 -114
View File
@@ -16,16 +16,14 @@
* 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: elab_pexpr.cc,v 1.28 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_pexpr.cc,v 1.13 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include "netmisc.h"
# include <iostream>
@@ -54,7 +52,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
return tmp;
}
@@ -63,26 +61,33 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
* expressions can include concatenation expressions. This requires
* that the subexpressions all have well-defined size (in spite of
* being in a parameter expression) in order to get a defined
* value. The sub-expressions themselves must also be value parameter
* value. The sub-expressions themsilves must also be value parameter
* expressions.
*/
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr* repeat = 0;
unsigned repeat = 1;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
value and set the repeat count.
XXXX Potential bug XXX In principle, the repeat expression
can have a parameter name in it. Since where are in the
working of parameters now, we will not be able to
accurately evaluate such expressions. So eventually, I will
need to be able to defer the evaluation of the expression. */
if (repeat_) {
repeat = repeat_->elaborate_pexpr(des, scope);
if (repeat == 0) {
verinum*vrep = repeat_->eval_const(des, scope);
if (vrep == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
return 0;
}
/* continue on even if the repeat expression doesn't
work, as we can find more errors. */
repeat = vrep->as_ulong();
delete vrep;
}
/* Make the empty concat expression. */
@@ -99,17 +104,17 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
/* If this parameter is a NetEParam, then put off
the width check for later. */
} else if (! ex->has_width()) {
if (! ex->has_width()) {
cerr << ex->get_line() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
} else if (ex->expr_width() == 0) {
cerr << ex->get_line() << ": internal error: "
<< "Operand of concatenation has no width: "
<< *ex << endl;
des->errors += 1;
}
tmp->set(idx, ex);
@@ -120,7 +125,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
return elaborate_expr(des, scope);
}
/*
@@ -131,55 +136,31 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
pform_name_t path = path_;
name_component_t name_tail = path_.back();
path.pop_back();
hname_t path = path_;
char*name = path.remove_tail_name();
NetScope*pscope = scope;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, path);
pscope = des->find_scope(scope, tmp);
}
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
const NetExpr*ex_msb;
const NetExpr*ex_lsb;
const NetExpr*ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
const NetExpr*ex = pscope->get_parameter(name);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
delete name;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
res->set_line(*this);
assert(res);
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 "
if (msb_ || lsb_ || idx_) {
cerr << get_line() << ": error: Cannot bit/part select "
"bits of parameters." << endl;
des->errors += 1;
break;
case index_component_t::SEL_BIT:
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
break;
}
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res);
delete name;
return res;
}
@@ -188,13 +169,13 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
{
return elaborate_expr(des, sc, -1, false);
return elaborate_expr(des, sc);
}
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
return elaborate_expr(des, scope);
}
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
@@ -243,62 +224,6 @@ 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
* contain unsized numbers.
*
* Revision 1.24 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.23 2006/02/02 02:43:58 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.22 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.21 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.20 2003/05/30 02:55:32 steve
* Support parameters in real expressions and
* as real expressions, and fix multiply and
* divide with real results.
*
* Revision 1.19 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.18 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.17 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
* Revision 1.16 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/05/06 02:30:27 steve
* Allow parameters in concatenation of widths are defined.
*
* Revision 1.14 2002/05/05 21:11:50 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Add the builtin $signed system function.
*
* Revision 1.13 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
+133 -486
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000 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
@@ -16,15 +16,13 @@
* 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: elab_scope.cc,v 1.46 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_scope.cc,v 1.13 2001/12/30 04:47:57 steve Exp $"
#endif
# include "config.h"
# include "compiler.h"
# include "netmisc.h"
# include "config.h"
# include <iostream>
# include <stdio.h>
/*
* Elaboration happens in two passes, generally. The first scans the
@@ -37,23 +35,14 @@
# include "PEvent.h"
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
# include "netlist.h"
# include "util.h"
# include <typeinfo>
# include <assert.h>
bool Module::elaborate_scope(Design*des, NetScope*scope,
const replace_t&replacements) const
bool Module::elaborate_scope(Design*des, NetScope*scope) const
{
if (debug_scopes) {
cerr << get_line() << ": debug: Elaborate scope "
<< scope_path(scope) << "." << endl;
}
// Generate all the parameters that this instance of this
// module introduces to the design. This loop elaborates the
// parameters, but doesn't evaluate references to
@@ -65,8 +54,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// the pform and just place a NetEParam placeholder in the
// place of the elaborated expression.
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
typedef map<string,PExpr*>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
// This loop scans the parameters in the module, and creates
@@ -75,22 +64,13 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
NetEParam*tmp = new NetEParam;
tmp->set_line(*((*cur).second.expr));
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false);
scope->set_parameter((*cur).first, new NetEParam);
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
NetEParam*tmp = new NetEParam;
tmp->set_line(*((*cur).second.expr));
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false);
scope->set_parameter((*cur).first, new NetEParam);
}
@@ -102,90 +82,23 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
PExpr*ex = (*cur).second.expr;
PExpr*ex = (*cur).second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = (*cur).second.signed_flag;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
}
if (signed_flag) {
/* If explicitly signed, then say so. */
val->cast_signed(true);
} else if ((*cur).second.msb) {
/* If there is a range, then the signedness comes
from the type and not the expression. */
val->cast_signed(signed_flag);
} else {
/* otherwise, let the expression describe
itself. */
signed_flag = val->has_sign();
}
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
val = scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
/* run parameter replacements that were collected from the
containing scope and meant for me. */
for (replace_t::const_iterator cur = replacements.begin()
; cur != replacements.end() ; cur ++) {
NetExpr*val = (*cur).second;
if (debug_scopes) {
cerr << get_line() << ": debug: "
<< "Replace " << (*cur).first
<< " with expression " << *val
<< " from " << val->get_line() << "." << endl;
}
bool flag = scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< scope_path(scope) << "." << endl;
}
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
PExpr*ex = (*cur).second.expr;
PExpr*ex = (*cur).second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
val = scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
@@ -197,10 +110,10 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// It is OK to elaborate the expressions of the defparam here
// because Verilog requires that the expressions only use
// local parameter names. It is *not* OK to do the override
// here because the parameter receiving the assignment may be
// here becuase the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (pform_parm_it_t cur = defparms.begin()
for (hparm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -211,40 +124,18 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
scope->defparams[(*cur).first] = val;
}
// Evaluate the attributes. Evaluate them in the scope of the
// module that the attribute is attached to. Is this correct?
unsigned nattr;
attrib_list_t*attr = evaluate_attributes(attributes, nattr, des, scope);
for (unsigned idx = 0 ; idx < nattr ; idx += 1)
scope->attribute(attr[idx].key, attr[idx].val);
delete[]attr;
// Generate schemes can create new scopes in the form of
// generated code. Scan the generate schemes, and *generate*
// new scopes, which is slightly different from simple
// elaboration.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
// Tasks introduce new scopes, so scan the tasks in this
// module. Create a scope for the task and pass that to the
// elaborate_scope method of the PTask for detailed
// processing.
typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
typedef map<string,PTask*>::const_iterator tasks_it_t;
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
NetScope*task_scope = new NetScope(scope, use_name,
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -254,13 +145,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// perspective of scopes. So handle them exactly the same
// way.
typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
typedef map<string,PFunction*>::const_iterator funcs_it_t;
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
NetScope*func_scope = new NetScope(scope, use_name,
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -270,6 +160,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// scan all of them to create those scopes.
typedef list<PGate*>::const_iterator gates_it_t;
for (gates_it_t cur = gates_.begin()
; cur != gates_.end() ; cur ++ ) {
@@ -290,11 +181,11 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
}
// Scan through all the named events in this scope. We do not
// need anything more than the current scope to do this
// need anything more then the current scope to do this
// elaboration, so do it now. This allows for normal
// elaboration to reference these events.
for (map<perm_string,PEvent*>::const_iterator et = events.begin()
for (map<string,PEvent*>::const_iterator et = events.begin()
; et != events.end() ; et ++ ) {
(*et).second->elaborate_scope(des, scope);
@@ -303,116 +194,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
return des->errors == 0;
}
bool PGenerate::generate_scope(Design*des, NetScope*container)
{
switch (scheme_type) {
case GS_LOOP:
return generate_scope_loop_(des, container);
default:
cerr << get_line() << ": sorry: Generate of this sort"
<< " is not supported yet!" << endl;
return false;
}
}
/*
* This is the elaborate scope method for a generate loop.
*/
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{
// We're going to need a genvar...
int genvar;
// The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression
// the same way any other paramter value is evaluated.
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) {
cerr << get_line() << ": error: Cannot evaluate genvar"
<< " init expression: " << *loop_init << endl;
des->errors += 1;
return false;
}
genvar = init->value().as_long();
delete init_ex;
if (debug_elaborate)
cerr << get_line() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index;
container->genvar_tmp_val = 0;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
while (test->value().as_long()) {
// The actual name of the scope includes the genvar so
// that each instance has a unique name in the
// container. The format of using [] is part of the
// Verilog standard.
hname_t use_name (scope_name, genvar);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create generated scope " << use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
// Set in the scope a localparam for the value of the
// genvar within this instance of the generate
// block. Code within this scope thus has access to the
// genvar as a constant.
{
verinum genvar_verinum(genvar);
genvar_verinum.has_sign(true);
NetEConstParam*gp = new NetEConstParam(scope,
loop_index,
genvar_verinum);
scope->set_localparam(loop_index, gp);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create implicit localparam "
<< loop_index << " = " << genvar_verinum << endl;
}
// Scan the generated scope for gates that may create
// their own scopes.
typedef list<PGate*>::const_iterator pgate_list_it_t;
for (pgate_list_it_t cur = gates.begin()
; cur != gates.end() ; cur ++) {
(*cur) ->elaborate_scope(des, scope);
}
scope_list_.push_back(scope);
// Calculate the step for the loop variable.
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
assert(step);
if (debug_elaborate)
cerr << get_line() << ": debug: genvar step from "
<< genvar << " to " << step->value().as_long() << endl;
genvar = step->value().as_long();
container->genvar_tmp_val = genvar;
delete step;
delete test_ex;
test_ex = elab_and_eval(des, container, loop_test, -1);
test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
}
// Clear the genvar_tmp field in the scope to reflect that the
// genvar is no longer value for evaluating expressions.
container->genvar_tmp = perm_string();
return true;
}
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
{
if (get_name() == "") {
@@ -429,7 +210,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(hname_t(get_name()))) {
if (NetScope*tmp = sc->child(get_name())) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
@@ -452,149 +233,83 @@ 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 "
<< scope_path(sc) << "." << get_name() << " within "
<< scope_path(scn) << "." << endl;
<< sc->name() << "." << get_name() << " within "
<< scn->name() << "." << endl;
des->errors += 1;
return;
}
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
assert( (msb == 0) || (lsb != 0) );
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
long instance_low = 0;
long instance_high = 0;
long instance_count = 1;
bool instance_array = false;
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
if (msb) {
instance_array = true;
instance_high = msb->value().as_long();
instance_low = lsb->value().as_long();
if (instance_high > instance_low)
instance_count = instance_high - instance_low + 1;
else
instance_count = instance_low - instance_high + 1;
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrices or named
// overrides.
delete mse;
delete lse;
typedef map<string,PExpr*>::const_iterator mparm_it_t;
map<string,PExpr*> replace;
// Positional parameter overrides are matched to parameter
// names by using the param_names list of parameter
// names. This is an ordered list of names so the first name
// is parameter 0, the second parameter 1, and so on.
if (overrides_) {
assert(parms_ == 0);
list<string>::const_iterator cur = mod->param_names.begin();
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
replace[*cur] = (*overrides_)[idx];
idx += 1;
cur ++;
}
}
NetScope::scope_vec_t instances (instance_count);
if (debug_scopes) {
cerr << get_line() << ": debug: Create " << instance_count
<< " instances of " << get_name()
<< "." << endl;
}
// Run through the module instances, and make scopes out of
// them. Also do parameter overrides that are done on the
// instantiation line.
for (int idx = 0 ; idx < instance_count ; idx += 1) {
hname_t use_name (get_name());
if (instance_array) {
int instance_idx = idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
instance_idx = instance_low - idx;
use_name = hname_t(get_name(), instance_idx);
}
if (debug_scopes) {
cerr << get_line() << ": debug: Module instance " << use_name
<< " becomes child of " << scope_path(sc)
<< "." << endl;
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
my_scope->default_nettype(mod->default_nettype);
instances[idx] = my_scope;
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrides or named
// overrides.
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
map<perm_string,PExpr*> replace;
// Positional parameter overrides are matched to parameter
// names by using the param_names list of parameter
// names. This is an ordered list of names so the first name
// is parameter 0, the second parameter 1, and so on.
if (overrides_) {
assert(parms_ == 0);
list<perm_string>::const_iterator cur
= mod->param_names.begin();
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
replace[*cur] = (*overrides_)[idx];
idx += 1;
cur ++;
}
}
// Named parameter overrides carry a name with each override
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
replace[parms_[idx].name] = parms_[idx].parm;
}
Module::replace_t replace_net;
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
for (mparm_it_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
replace_net[(*cur).first] = val;
}
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope, replace_net);
// Named parameter overrides carry a name with each override
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
replace[parms_[idx].name] = parms_[idx].parm;
}
/* Stash the instance array of scopes into the parent
scope. Later elaboration passes will use this vector to
further elaborate the array. */
sc->instance_arrays[get_name()] = instances;
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
for (mparm_it_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
val = my_scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
}
/*
@@ -613,10 +328,6 @@ void PEvent::elaborate_scope(Design*des, NetScope*scope) const
void PFunction::elaborate_scope(Design*des, NetScope*scope) const
{
assert(scope->type() == NetScope::FUNC);
if (statement_)
statement_->elaborate_scope(des, scope);
}
void PTask::elaborate_scope(Design*des, NetScope*scope) const
@@ -646,8 +357,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
{
NetScope*my_scope = scope;
if (name_ != 0) {
my_scope = new NetScope(scope, hname_t(name_), bl_type_==BL_PAR
if (name_ != "") {
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -658,7 +369,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
}
/*
* The case statement itself does not introduce scope, but contains
* The case statement itseof does not introduce scope, but contains
* other statements that may be named blocks. So scan the case items
* with the elaborate_scope method.
*/
@@ -756,118 +467,54 @@ 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
*
* Revision 1.43 2007/03/08 06:11:35 steve
* Elaborate scopes of modules instantated in generate loops.
*
* Revision 1.42 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.41 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.40 2006/04/12 05:05:03 steve
* Use elab_and_eval to evaluate genvar expressions.
*
* Revision 1.39 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.38 2006/03/30 01:49:07 steve
* Fix instance arrays indexed by overridden parameters.
*
* Revision 1.37 2006/03/18 22:53:38 steve
* Support more parameter syntax.
*
* Revision 1.36 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.35 2004/09/10 00:15:17 steve
* Missing stdio.h header for warnings.
*
* Revision 1.34 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.33 2004/08/26 04:02:03 steve
* Add support for localparam ranges.
*
* Revision 1.32 2004/06/13 04:56:54 steve
* Add support for the default_nettype directive.
*
* Revision 1.31 2004/05/25 19:21:06 steve
* More identifier lists use perm_strings.
*
* Revision 1.30 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.29 2004/02/19 07:06:57 steve
* LPM, logic and Variables have perm_string names.
*
* Revision 1.28 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items.
*
* Revision 1.27 2003/09/13 01:01:51 steve
* Spelling fixes.
*
* Revision 1.26 2003/08/28 04:11:17 steve
* Spelling patch.
*
* Revision 1.25 2003/06/24 01:38:02 steve
* Various warnings fixed.
*
* Revision 1.24 2003/06/20 00:53:19 steve
* Module attributes from the parser
* through to elaborated form.
*
* Revision 1.23 2003/06/16 00:34:08 steve
* Functions can have sub-scope.
*
* Revision 1.22 2003/06/13 19:10:46 steve
* Properly manage real variables in subscopes.
*
* Revision 1.21 2003/05/30 02:55:32 steve
* Support parameters in real expressions and
* as real expressions, and fix multiply and
* divide with real results.
*
* Revision 1.20 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.19 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.18 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.17 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.16 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*
* Revision 1.15 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.14 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2001/12/30 04:47:57 steve
* Properly handle empty target in positionla parameter override.
*
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.11 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.10 2001/10/09 02:01:04 steve
* Tasks can have sub-scopes.
*
* Revision 1.9 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.8 2001/04/28 23:18:08 steve
* UDP instances need not have user supplied names.
*
* Revision 1.7 2000/12/16 01:45:48 steve
* Detect recursive instantiations (PR#2)
*
* Revision 1.6 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.5 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.4 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.3 2000/03/12 17:09:41 steve
* Support localparam.
*
* Revision 1.2 2000/03/11 03:25:52 steve
* Locate scopes in statements.
*
* Revision 1.1 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
*/
+159 -475
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000 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
@@ -16,8 +16,8 @@
* 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: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.20 2002/01/26 05:28:28 steve Exp $"
#endif
# include "config.h"
@@ -27,14 +27,11 @@
# include "Module.h"
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PTask.h"
# include "PWire.h"
# include "compiler.h"
# 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
@@ -42,10 +39,8 @@
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
NetNet*sig)
const hname_t&name)
{
perm_string name = sig->name();
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
@@ -56,15 +51,9 @@ 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 (pname == name)
if (pp->expr[cc]->path() == name)
return true;
}
}
@@ -72,41 +61,27 @@ 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) {
Module::port_t*pp = ports[idx];
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
Module::port_t*pp = ports_[idx];
if (pp == 0)
continue;
map<pform_name_t,PWire*>::const_iterator wt;
map<hname_t,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
pform_name_t port_path (pp->expr[cc]->path());
wt = wires_.find(port_path);
hname_t port_path (pp->expr[cc]->path());
wt = wl.find(port_path);
if (wt == wires_.end()) {
if (wt == wl.end()) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
@@ -126,11 +101,14 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
}
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
; wt != wires_.end() ; wt ++ ) {
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
PWire*cur = (*wt).second;
NetNet*sig = cur->elaborate_sig(des, scope);
cur->elaborate_sig(des, scope);
NetNet*sig = scope->find_signal_in_child(cur->path());
// If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that
@@ -142,10 +120,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
if (! signal_is_in_port(ports, sig)) {
hname_t name = (*wt).first;
if (! signal_is_in_port(ports_, name)) {
cerr << cur->get_line() << ": error: Signal "
<< sig->name() << " has a declared direction "
<< name << " has a declared direction "
<< "but is not a port." << endl;
des->errors += 1;
}
@@ -177,16 +157,6 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
des->errors += 1;
}
}
// Run through all the generate schemes to enaborate the
// signals that they hold. Note that the generate schemes hold
// the scopes that they instantiated, so we don't pass any
// scope in.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> elaborate_sig(des);
}
// Get all the gates of the module and elaborate them by
@@ -204,17 +174,15 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
NetScope*fscope = scope->child((*cur).first);
if (scope == 0) {
cerr << (*cur).second->get_line() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl;
<< " missing in " << scope->name() << "." << endl;
des->errors += 1;
continue;
}
@@ -227,11 +195,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
// elaborate the ports of the tasks defined within this
// module. Run through them now.
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
typedef map<string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child( hname_t((*cur).first) );
NetScope*tscope = scope->child((*cur).first);
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
@@ -242,86 +210,31 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
Module*rmod) const
{
bool flag = true;
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = instance[idx];
assert(my_scope);
if (my_scope->parent() != scope) {
cerr << get_line() << ": internal error: "
<< "Instance " << scope_path(my_scope)
<< " is in parent " << scope_path(my_scope->parent())
<< " instead of " << scope_path(scope)
<< endl;
}
assert(my_scope->parent() == scope);
if (! rmod->elaborate_sig(des, my_scope))
flag = false;
// Missing module instance names have already been rejected.
assert(get_name() != "");
if (msb_) {
cerr << get_line() << ": sorry: Module instantiation arrays "
"are not yet supported." << endl;
des->errors += 1;
return false;
}
return flag;
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = scope->child(get_name());
assert(my_scope);
return rmod->elaborate_sig(des, my_scope);
}
bool PGenerate::elaborate_sig(Design*des) const
{
bool flag = true;
typedef list<NetScope*>::const_iterator scope_list_it_t;
for (scope_list_it_t cur = scope_list_.begin()
; cur != scope_list_.end() ; cur ++ ) {
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate nets in "
<< "scope " << scope_path(*cur) << endl;
flag = elaborate_sig_(des, *cur) & flag;
}
return flag;
}
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
{
// Scan the declared PWires to elaborate the obvious signals
// in the current scope.
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
for (wires_it_t wt = wires.begin()
; wt != wires.end() ; wt ++ ) {
PWire*cur = (*wt).second;
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate PWire "
<< cur->path() << " in scope " << scope_path(scope) << endl;
cur->elaborate_sig(des, scope);
}
typedef list<PGate*>::const_iterator pgate_list_it_t;
for (pgate_list_it_t cur = gates.begin()
; cur != gates.end() ; cur ++) {
(*cur) ->elaborate_sig(des, scope);
}
return true;
}
/*
* A function definition exists within an elaborated module. This
* matters when elaborating signals, as the ports of the function are
* created as signals/variables for each instance of the
* function. That is why PFunction has an elaborate_sig method.
* A function definition exists within an elaborated module.
*/
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
{
perm_string fname = scope->basename();
string fname = scope->basename();
assert(scope->type() == NetScope::FUNC);
/* Make sure the function has at least one input port. If it
@@ -335,88 +248,21 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
des->errors += 1;
}
NetNet*ret_sig = 0;
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
/* Create the signals/variables of the return value and write
them into the function scope. */
switch (return_type_.type) {
case PTF_REG:
case PTF_REG_S:
if (return_type_.range) {
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0], -1);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1], -1);
assert(le);
long mnum = 0, lnum = 0;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
mnum = tmp->value().as_long();
} else {
cerr << me->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *me << "." << endl;
des->errors += 1;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
lnum = tmp->value().as_long();
} else {
cerr << le->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *le << "." << endl;
des->errors += 1;
}
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
} else {
ret_sig = new NetNet(scope, fname, NetNet::REG);
}
ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_INTEGER:
ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_TIME:
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
ret_sig->set_line(*this);
ret_sig->set_signed(false);
ret_sig->set_isint(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_REAL:
case PTF_REALTIME:
ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL);
break;
default:
cerr << get_line() << ": internal error: I don't know how "
<< "to deal with return type of function "
<< scope->basename() << "." << endl;
/* Get the reg for the return value. I know the name of the
reg variable, and I know that it is in this scope, so look
it up directly. */
ports[0] = scope->find_signal(scope->basename());
if (ports[0] == 0) {
cerr << get_line() << ": internal error: function scope "
<< scope->name() << " is missing return reg "
<< fname << "." << endl;
scope->dump(cerr);
des->errors += 1;
return;
}
svector<NetNet*>ports (ports_? ports_->count() : 0);
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
@@ -424,38 +270,32 @@ 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>. */
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);
hname_t path = (*ports_)[idx]->path();
string pname = path.peek_name(1);
string ppath = path.peek_name(0);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->path()
<< " has wrong name for function "
<< scope_path(scope) << "." << endl;
<< scope->name() << "." << endl;
des->errors += 1;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope_path(scope) << " is missing port "
<< scope->name() << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
des->errors += 1;
}
ports[idx] = tmp;
ports[idx+1] = tmp;
}
NetFuncDef*def = 0;
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
assert(def);
NetFuncDef*def = new NetFuncDef(scope, ports);
scope->set_func_def(def);
}
@@ -479,34 +319,36 @@ 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>. */
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);
hname_t path = (*ports_)[idx]->path();
assert(path.peek_name(0) && path.peek_name(1));
/* 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. */
ivl_assert(*this, scope->basename() == scope_name);
if (scope->parent()->child(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
}
/* 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(port_name);
NetNet*tmp = scope->find_signal(path.peek_name(1));
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << port_name
<< " in scope " << scope_path(scope) << endl;
<< "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl;
scope->dump(cerr);
}
ports[idx] = tmp;
}
NetTaskDef*def = new NetTaskDef(scope, ports);
NetTaskDef*def = new NetTaskDef(scope->name(), ports);
scope->set_task_def(def);
}
@@ -518,30 +360,20 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire") so come the
* multiple properties of a wire (i.e. "input wire") so come the
* elaboration this creates an object in the design that represent the
* defined item.
*/
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
void 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. */
{ 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: "
<< "Bad scope component for name "
<< hname_ << endl;
assert(scope);
}
{ 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));
assert(scope);
}
}
@@ -559,12 +391,12 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
svector<long>mnum (msb_.count());
svector<long>lnum (msb_.count());
/* There may be places where the signal is declared as a
scalar. Count those here, for consistency check
scaler. Count those here, for consistency check
later. */
unsigned count_scalars = 0;
/* There may be multiple declarations of ranges, because
the symbol may have its range declared in e.g., input
the symbol may have its range declared in i.e. input
and reg declarations. Calculate *all* the numbers
here. I will resolve the values later. */
@@ -579,7 +411,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1);
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
@@ -587,20 +419,20 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
des->errors += 1;
return 0;
return;
}
mnum[idx] = tmp->value().as_long();
delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx], -1);
texpr = elab_and_eval(des, scope, lsb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*lsb_[idx] << "''." << endl;
des->errors += 1;
return 0;
return;
}
lnum[idx] = tmp->value().as_long();
@@ -616,7 +448,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return 0;
return;
}
@@ -629,7 +461,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << hname_ << "''" << endl;
des->errors += 1;
return 0;
return;
}
}
@@ -643,239 +475,50 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
unsigned nattrib = 0;
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
des, scope);
long array_s0 = 0;
long array_e0 = 0;
unsigned array_dimensions = 0;
/* If the ident has idx expressions, then this is a
memory. It can only have the idx registers after the msb
and lsb expressions are filled. And, if it has one index,
it has both. */
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
// If the register has indices, then this is a
// memory. Create the memory object.
verinum*lval = lidx_->eval_const(des, scope);
verinum*rval = ridx_->eval_const(des, scope);
if ((lexp == 0) || (rexp == 0)) {
if ((lval == 0) || (rval == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< hname_ << "''." << endl;
<< hname_.peek_tail_name() << "''." << endl;
des->errors += 1;
return 0;
return;
}
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
NetEConst*rcon = dynamic_cast<NetEConst*> (rexp);
assert(lval);
assert(rval);
if ((lcon == 0) || (rcon == 0)) {
cerr << get_line() << ": internal error: The indices "
<< "are not constant for array ``"
<< hname_ << "''." << endl;
des->errors += 1;
return 0;
}
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
verinum lval = lcon->value();
verinum rval = rcon->value();
long lnum = lval->as_long();
long rnum = rval->as_long();
delete lval;
delete rval;
NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
delete lexp;
delete rexp;
} else {
array_dimensions = 1;
array_s0 = lval.as_long();
array_e0 = rval.as_long();
/* Make a hierarchical make for the signal. */
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_attributes(attributes);
}
/* If the net type is supply0 or supply1, replace it
with a simple wire with a pulldown/pullup with supply
strength. In other words, transform:
supply0 foo;
to:
wire foo;
pulldown #(supply0) (foo);
This reduces the backend burden, and behaves exactly
the same. */
NetLogic*pull = 0;
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
? NetLogic::PULLUP
: NetLogic::PULLDOWN;
pull = new NetLogic(scope, scope->local_symbol(),
1, pull_type, wid);
pull->set_line(*this);
pull->pin(0).drive0(Link::SUPPLY);
pull->pin(0).drive1(Link::SUPPLY);
des->add_node(pull);
wtype = NetNet::WIRE;
if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Generate a SUPPLY pulldown for the "
<< "supply0 net." << endl;
}
}
perm_string name = peek_tail_name(hname_);
if (debug_elaborate) {
cerr << get_line() << ": debug: Create signal "
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
<< " in scope " << scope_path(scope) << endl;
}
NetNet*sig = array_dimensions > 0
? new NetNet(scope, name, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name, wtype, msb, lsb);
ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC;
if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Signal " << name
<< " in scope " << scope_path(scope)
<< " defaults to data type " << use_data_type << endl;
}
}
sig->data_type(use_data_type);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_isint(get_isint());
if (pull)
connect(sig->pin(0), pull->pin(0));
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
*
* Revision 1.48 2007/03/08 06:11:35 steve
* Elaborate scopes of modules instantated in generate loops.
*
* Revision 1.47 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.46 2007/03/06 05:22:49 steve
* Support signed function return values.
*
* Revision 1.45 2007/02/01 05:24:08 steve
* Include type in signal create message.
*
* Revision 1.44 2007/01/29 02:07:34 steve
* Types of task/function arguments set in multiple steps.
*
* Revision 1.43 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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.42 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.41 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.40 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.39 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.38 2005/02/13 01:15:07 steve
* Replace supply nets with wires connected to pullup/down supply devices.
*
* Revision 1.37 2004/12/11 02:31:25 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.36 2004/09/27 22:34:10 steve
* Cleanup and factoring of autoconf.
*
* Revision 1.35 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.34 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.33 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items.
*
* Revision 1.32 2003/09/20 05:24:00 steve
* Evaluate memory index constants using elab_and_eval.
*
* Revision 1.31 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.30 2003/06/24 01:38:02 steve
* Various warnings fixed.
*
* Revision 1.29 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.28 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.27 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.26 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.25 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.24 2002/08/05 04:18:45 steve
* Store only the base name of memories.
*
* Revision 1.23 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.22 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.21 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.20 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
@@ -908,5 +551,46 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
* Revision 1.11 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
*
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.9 2001/01/07 07:00:31 steve
* Detect port direction attached to non-ports.
*
* Revision 1.8 2001/01/04 04:47:51 steve
* Add support for << is signal indices.
*
* Revision 1.7 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.6 2000/12/04 17:37:04 steve
* Add Attrib class for holding NetObj attributes.
*
* Revision 1.5 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
* Revision 1.4 2000/09/07 22:37:48 steve
* ack, detect when lval fails.
*
* Revision 1.3 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.2 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.1 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
*/
+778 -1955
View File
File diff suppressed because it is too large Load Diff
+144 -156
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2000 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
@@ -16,8 +16,8 @@
* 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: emit.cc,v 1.89 2007/01/16 05:44:15 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.65 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -57,17 +57,18 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
return true;
}
bool NetArrayDq::emit_node(struct target_t*tgt) const
{
return tgt->lpm_array_dq(this);
}
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(this);
return true;
}
bool NetCAssign::emit_node(struct target_t*tgt) const
{
tgt->net_cassign(this);
return true;
}
bool NetCLShift::emit_node(struct target_t*tgt) const
{
tgt->lpm_clshift(this);
@@ -80,11 +81,6 @@ bool NetCompare::emit_node(struct target_t*tgt) const
return true;
}
bool NetConcat::emit_node(struct target_t*tgt) const
{
return tgt->concat(this);
}
bool NetConst::emit_node(struct target_t*tgt) const
{
return tgt->net_const(this);
@@ -102,9 +98,10 @@ bool NetFF::emit_node(struct target_t*tgt) const
return true;
}
bool NetLiteral::emit_node(struct target_t*tgt) const
bool NetForce::emit_node(struct target_t*tgt) const
{
return tgt->net_literal(this);
tgt->net_force(this);
return true;
}
bool NetModulo::emit_node(struct target_t*tgt) const
@@ -125,34 +122,10 @@ bool NetMux::emit_node(struct target_t*tgt) const
return true;
}
bool NetPartSelect::emit_node(struct target_t*tgt) const
bool NetRamDq::emit_node(struct target_t*tgt) const
{
return tgt->part_select(this);
}
bool NetReplicate::emit_node(struct target_t*tgt) const
{
return tgt->replicate(this);
}
bool NetSignExtend::emit_node(struct target_t*tgt) const
{
return tgt->sign_extend(this);
}
bool NetUReduce::emit_node(struct target_t*tgt) const
{
return tgt->ureduce(this);
}
bool NetSysFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_sysfunction(this);
}
bool NetUserFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_function(this);
tgt->lpm_ram_dq(this);
return true;
}
bool NetBUFZ::emit_node(struct target_t*tgt) const
@@ -183,6 +156,18 @@ bool NetAssignNB::emit_proc(struct target_t*tgt) const
return true;
}
bool NetAssignMem::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem(this);
return true;
}
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem_nb(this);
return true;
}
bool NetBlock::emit_proc(struct target_t*tgt) const
{
return tgt->proc_block(this);
@@ -343,42 +328,34 @@ void NetScope::emit_scope(struct target_t*tgt) const
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
/* Run the signals again, but this time to connect the
delay paths. This is done as a second pass because
the paths reference other signals that may be later
in the list. We can do it here becase delay paths are
always connected within the scope. */
cur = signals_->sig_next_;
do {
tgt->signal_paths(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
if (memories_) {
NetMemory*cur = memories_->snext_;
do {
tgt->memory(cur);
cur = cur->snext_;
} while (cur != memories_->snext_);
}
}
bool NetScope::emit_defs(struct target_t*tgt) const
void NetScope::emit_defs(struct target_t*tgt) const
{
bool flag = true;
switch (type_) {
case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
cur->emit_defs(tgt);
break;
case FUNC:
flag &= tgt->func_def(this);
tgt->func_def(this);
break;
case TASK:
tgt->task_def(this);
break;
default: /* BEGIN_END and FORK_JOIN, do nothing */
break;
}
return flag;
}
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
@@ -386,50 +363,42 @@ void NetWhile::emit_proc_recurse(struct target_t*tgt) const
proc_->emit_proc(tgt);
}
int Design::emit(struct target_t*tgt) const
bool Design::emit(struct target_t*tgt) const
{
int rc = 0;
bool rc = true;
if (tgt->start_design(this) == false)
return -2;
rc = rc && tgt->start_design(this);
if (rc == false)
return false;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
// emit nodes
bool nodes_rc = true;
if (nodes_) {
NetNode*cur = nodes_->node_next_;
do {
nodes_rc = nodes_rc && cur->emit_node(tgt);
rc = rc && cur->emit_node(tgt);
cur = cur->node_next_;
} while (cur != nodes_->node_next_);
}
// emit task and function definitions
bool tasks_rc = true;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
tasks_rc &= (*scope)->emit_defs(tgt);
(*scope)->emit_defs(tgt);
// emit the processes
bool proc_rc = true;
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
proc_rc &= idx->emit(tgt);
rc = rc && idx->emit(tgt);
rc = tgt->end_design(this);
if (nodes_rc == false)
return -1;
if (tasks_rc == false)
return -2;
if (proc_rc == false)
return -3;
if (tgt->end_design(this) != 0)
rc = false;
return rc;
}
@@ -449,19 +418,9 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_const(this);
}
void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_param(this);
}
void NetECReal::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_creal(this);
}
void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_rparam(this);
tgt->expr_memory(this);
}
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
@@ -470,11 +429,6 @@ void NetEParam::expr_scan(struct expr_scan_t*tgt) const
<< endl;
}
void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_event(this);
}
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_scope(this);
@@ -500,6 +454,11 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_signal(this);
}
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_subsignal(this);
}
void NetETernary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ternary(this);
@@ -510,7 +469,7 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_unary(this);
}
int emit(const Design*des, const char*type)
bool emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
const struct target*tgt = target_table[idx];
@@ -518,87 +477,116 @@ int emit(const Design*des, const char*type)
return des->emit(tgt->meth);
}
cerr << "error: Code generator type " << type
<< " not found." << endl;
return -1;
}
/*
* $Log: emit.cc,v $
* Revision 1.89 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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
* Revision 1.65 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.88 2006/11/10 05:44:44 steve
* Process delay paths in second path over signals.
* Revision 1.64 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.87 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
* Revision 1.63 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.86 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
* Revision 1.62 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Revision 1.85 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.84 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
* Revision 1.61 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
*
* Revision 1.83 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
* Revision 1.60 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.82 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
* Revision 1.59 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.81 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
* Revision 1.58 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.80 2005/01/22 01:06:55 steve
* Change case compare from logic to an LPM node.
* Revision 1.57 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.79 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
* Revision 1.56 2001/03/27 03:31:06 steve
* Support error code from target_t::end_design method.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
* Revision 1.55 2000/11/04 01:54:01 steve
* Modifications in support of gcc 2.96
*
* Revision 1.78 2004/12/11 02:31:26 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.54 2000/09/26 01:35:42 steve
* Remove the obsolete NetEIdent class.
*
* Revision 1.77 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
* Revision 1.53 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.76 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
* Revision 1.52 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate.
*
* Revision 1.75 2003/09/13 01:30:07 steve
* Missing case warnings.
* Revision 1.51 2000/08/14 04:39:56 steve
* add th t-dll functions for net_const, net_bufz and processes.
*
* Revision 1.74 2003/05/30 02:55:32 steve
* Support parameters in real expressions and
* as real expressions, and fix multiply and
* divide with real results.
* Revision 1.50 2000/08/09 03:43:45 steve
* Move all file manipulation out of target class.
*
* Revision 1.73 2003/04/22 04:48:29 steve
* Support event names as expressions elements.
* Revision 1.49 2000/08/08 01:50:42 steve
* target methods need not take a file stream.
*
* Revision 1.72 2003/03/10 23:40:53 steve
* Keep parameter constants for the ivl_target API.
* Revision 1.48 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.71 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
* Revision 1.47 2000/07/29 16:21:08 steve
* Report code generation errors through proc_delay.
*
* Revision 1.46 2000/07/27 05:13:44 steve
* Support elaboration of disable statements.
*
* Revision 1.45 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
* Revision 1.44 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.43 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.42 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.41 2000/04/23 03:45:24 steve
* Add support for the procedural release statement.
*
* Revision 1.40 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.39 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*/
+26 -159
View File
@@ -16,8 +16,8 @@
* 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: eval.cc,v 1.47 2007/06/04 19:14:06 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.26 2001/12/29 22:10:10 steve Exp $"
#endif
# include "config.h"
@@ -26,15 +26,14 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
verinum* PExpr::eval_const(Design*, NetScope*) const
verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
@@ -48,7 +47,9 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
switch (op_) {
case '+': {
if (l->is_defined() && r->is_defined()) {
res = new verinum(*l + *r);
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv+rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
@@ -56,7 +57,9 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
}
case '-': {
if (l->is_defined() && r->is_defined()) {
res = new verinum(*l - *r);
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
@@ -64,7 +67,9 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
}
case '*': {
if (l->is_defined() && r->is_defined()) {
res = new verinum(*l * *r);
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv * rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
@@ -90,26 +95,6 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
}
break;
}
case '>': {
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv > rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '<': {
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv < rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case 'l': { // left shift (<<)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
@@ -143,89 +128,45 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
delete r;
return res;
}
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
{
verinum*accum = parms_[0]->eval_const(des, scope);
if (accum == 0)
return 0;
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
verinum*tmp = parms_[idx]->eval_const(des, scope);
if (tmp == 0) {
delete accum;
return 0;
}
assert(tmp);
*accum = concat(*accum, *tmp);
delete tmp;
}
return accum;
}
/*
* Evaluate an identifier as a constant expression. This is only
* possible if the identifier is that of a parameter.
*/
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
verinum* PEIdent::eval_const(const Design*des, const 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(name_tail.name,scope->genvar_tmp) == 0) {
return new verinum(scope->genvar_tmp_val);
}
symbol_search(des, scope, path_, net, expr, eve);
const NetExpr*expr = des->find_parameter(scope, path_);
if (expr == 0)
return 0;
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
if (eval == 0) {
cerr << get_line() << ": internal error: Unable to evaluate "
<< "constant expression (parameter=" << path_
<< "): " << *expr << endl;
assert(msb_ == 0);
if (dynamic_cast<const NetEParam*>(expr)) {
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
path_ << "'' in this scope: " << scope->name() << endl;
return 0;
}
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
assert(eval);
if (!name_tail.index.empty())
return 0;
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(Design*, NetScope*) const
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(Design*, NetScope*) const
verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
return new verinum(value());
}
verinum* PEString::eval_const(Design*, NetScope*) const
{
return new verinum(string(text_));
}
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
@@ -245,7 +186,7 @@ verinum* PETernary::eval_const(Design*des, NetScope*scope) const
}
}
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
@@ -259,7 +200,7 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
/* We need to expand the value a bit if we are
taking the 2's complement so that we are
guaranteed to not overflow. */
verinum tmp ((uint64_t)0, val->len()+1);
verinum tmp (0UL, val->len()+1);
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
tmp.set(idx, val->get(idx));
@@ -276,80 +217,6 @@ verinum* PEUnary::eval_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.
*
* Revision 1.44 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
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.43 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
* Revision 1.42 2006/05/19 04:07:24 steve
* eval_const is not strict.
*
* Revision 1.41 2006/05/17 16:49:30 steve
* Error message if concat expression cannot evaluate.
*
* Revision 1.40 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.39 2005/12/07 04:04:23 steve
* Allow constant concat expressions.
*
* Revision 1.38 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* Revision 1.37 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.36 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.35 2003/04/14 03:40:21 steve
* Make some effort to preserve bits while
* operating on constant values.
*
* Revision 1.34 2003/03/26 06:16:18 steve
* Evaluate > and < in constant expressions.
*
* Revision 1.33 2003/03/10 23:40:53 steve
* Keep parameter constants for the ivl_target API.
*
* Revision 1.32 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.31 2002/10/13 05:01:07 steve
* More verbose eval_const assert message.
*
* Revision 1.30 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2002/06/07 02:57:54 steve
* Simply give up on constants with indices.
*
* Revision 1.28 2002/06/06 18:57:04 steve
* Better error for identifier index eval.
*
* Revision 1.27 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.26 2001/12/29 22:10:10 steve
* constant eval of arithmetic with x and z.
*
-109
View File
@@ -1,109 +0,0 @@
/*
* Copyright (c) 2002-2004 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: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
# include "util.h"
# include "PExpr.h"
# include "netlist.h"
# include <iostream>
# include <assert.h>
/*
* The evaluate_attributes function evaluates the attribute
* expressions from the map, and returns a table in a form suitable
* for passing to netlist devices.
*/
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
Design*des, NetScope*scope)
{
natt = att.size();
if (natt == 0)
return 0;
attrib_list_t*table = new attrib_list_t [natt];
unsigned idx = 0;
typedef map<perm_string,PExpr*>::const_iterator iter_t;
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
table[idx].key = (*cur).first;
PExpr*exp = (*cur).second;
/* If the attribute value is given in the source, then
evaluate it as a constant. If the value is not
given, then assume the value is 1. */
verinum*tmp;
if (exp)
tmp = exp->eval_const(des, scope);
else
tmp = new verinum(1);
if (tmp == 0)
cerr << "internal error: no result for " << *exp << endl;
assert(tmp);
table[idx].val = *tmp;
delete tmp;
}
assert(idx == natt);
return table;
}
/*
* $Log: eval_attrib.cc,v $
* Revision 1.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.
*
* Revision 1.7 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/08/10 21:59:39 steve
* The default attribute value is 1.
*
* Revision 1.3 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*
* Revision 1.2 2002/06/03 03:55:14 steve
* compile warnings.
*
* Revision 1.1 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
*/
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_rconst.cc,v 1.4 2001/11/07 04:01:59 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
{
return 0;
}
verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
{
verireal*res = new verireal;
*res = *value_;
return res;
}
verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
{
verireal*res = new verireal(value_->as_long());
return res;
}
verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
{
verireal*lef = left_->eval_rconst(des, scope);
verireal*rig = right_->eval_rconst(des, scope);
verireal*res = 0;
switch (op_) {
case '*':
if (lef == 0)
break;
if (rig == 0)
break;
res = new verireal;
*res = (*lef) * (*rig);
break;
default:
break;
}
delete lef;
delete rig;
return res;
}
verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
{
verinum* val = eval_const(des, scope);
if (val == 0)
return 0;
verireal*res = new verireal(val->as_long());
delete val;
return res;
}
/*
* $Log: eval_rconst.cc,v $
* Revision 1.4 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.3 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* 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/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
*/
+300 -870
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -1,3 +0,0 @@
,*
hello_vpi.vpi
show_vcd.vcd
-1035
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -26,21 +26,21 @@
* Compile this program with the command:
*
* iverilog -ohello hello.vl
*
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
* vvp hello
*
*
* ./hello
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
* manual page.
*/
module main();
initial
initial
begin
$display("Hello, World");
$finish ;
-81
View File
@@ -1,81 +0,0 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: hello_vpi.c,v 1.5 2007/01/17 05:35:48 steve Exp $"
#endif
/*
* This file contains an example VPI module to demonstrate the tools
* to create vpi modules. To compile this module, use the iverilog-vpi
* command like so:
*
* iverilog-vpi hello_vpi.c
*
* The result is the hello_vpi.vpi module. See the hello_vpi.vl
* program for example Verilog code to call this module.
*/
# include <vpi_user.h>
static PLI_INT32 my_hello_calltf(char *xx)
{
vpi_printf("Hello World, from VPI.\n");
return 0;
}
static void my_hello_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$my_hello";
tf_data.calltf = my_hello_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
vpi_register_systf(&tf_data);
}
/*
* This is a table of register functions. This table is the external
* symbol that the simulator looks for when loading this .vpi module.
*/
void (*vlog_startup_routines[])() = {
my_hello_register,
0
};
/*
* $Log: hello_vpi.c,v $
* Revision 1.5 2007/01/17 05:35:48 steve
* Fix typo is hello_vpi.c example.
*
* Revision 1.4 2006/10/30 22:46:25 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2002/04/18 03:25:16 steve
* More examples.
*
*/
-49
View File
@@ -1,49 +0,0 @@
/*
* Copyright (c) 2002 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
* 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
*/
/*
* Here we have the canonical "Hello, World" program written in Verilog,
* with VPI. It uses the hello_vpi.vpi module that is compiled from
* the hello_vpi.c program also in this directory. See the
* hello_vpi.c for instructions on how to compile it.
*
* Compile this program with the command:
*
* iverilog -ohello_vpi hello_vpi.vl
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
* vvp -M. -mhello_vpi hello_vpi
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
* manual page.
*/
module main();
initial
begin
$my_hello;
$finish ;
end
endmodule
+12 -12
View File
@@ -20,36 +20,36 @@
/*
* This example program simulates a 16x1 ram, and is used as an
* example for using VCD output and waveform viewers.
*
*
* Like any other Verilog simulation, compile this program with the
* command:
*
*
* iverilog show_vcd.vl
*
*
* This will generate the show_vcd command in the current directory.
* When you run the command, you will see the output from all the
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
* The name of this file is set by the statement:
*
* $dumpfile("show_vcd.vcd");
*
*
* in the main module. The output file uses the standard VCD file format
* so can be viewed using off-the-shelf waveform viewers. The remaining
* steps describe how to use GTKWave to view the file. If you are using
* a different viewer, see the documentation for that tool.
*
*
* To view the output generated by running show_vcd, start the GTKWave
* viewer with the command:
*
* gtkwave show_vcd.vcd
*
*
* wave show_vcd.vcd
*
* The GTKWave program will display its main window, and show in a small
* status box (upper left corner) that it succeeded in loading the dump
* file. However, there are no waveforms displayed yet. Select signals to
* add to the waveform display using the menu selection:
*
* "Search --> Signal Search Tree"
*
*
* This will bring up a dialog box that shows in directory tree format
* the signals of the program. Select the signals you wish to view, and
* click one of the buttons on the bottom of the dialog box to display
@@ -60,7 +60,7 @@
* $dumpvars system tasks. The $dumpfile task tells the simulation where
* to write the VCD output. This task must be called once before the
* $dumpvars task is called.
*
*
* The $dumpvars task tells the simulation what variables to write to
* the VCD output. The first parameter is how far to descend while
* scanning a scope, and the remaining paramters are signals or scope
@@ -77,7 +77,7 @@ module ram16x1 (q, d, a, we, wclk);
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
@@ -88,7 +88,7 @@ module main;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
-378
View File
@@ -1,378 +0,0 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $"
*/
/*
* This module is a synthesizeable square-root function. It is also a
* detailed example of how to target Xilinx Virtex parts using
* Icarus Verilog. In fact, for no particular reason other than to
* be excessively specific, I will step through the process of
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
* generate a generic library part for larger Virtex designs.
*
* In addition to Icarus Verilog, you will need implementation
* software from Xilinx. As of this writing, this example was tested
* with Foundation 4.2i, but it should work the same with ISE and
* Webpack software.
*
* This example source contains all the Verilog needed to do
* everything described below. We use conditional compilation to
* select the bits of Verilog that are needed to perform each specific
* task.
*
* SIMULATE THE DESIGN
*
* This source file includes a simulation test bench. To compile the
* program to include this test bench, use the command line:
*
* iverilog -DSIMULATE=1 -oa.out sqrt-virtex.v
*
* This generates the file "a.out" that can then be executed with the
* command:
*
* vvp a.out
*
* This causes the simulation to run a long set of example sqrt
* calculations. Each result is checked by the test bench to assure
* that the result is valid. When it is done, the program prints
* "PASSED" and finishes the simulation.
*
* When you take a close look at the "main" module below, you will see
* that it uses Verilog constructs that are not synthesizeable. This
* is fine, as we will never try to synthesize it.
*
* LIBRARY PARTS
*
* One can use the sqrt32 module to generate an EDIF file suitable for
* use as a library part. This part can be imported to the Xilinx
* schematic editor, then placed like any other pre-existing
* macro. One can also pass the generated EDIF as a precompiled macro
* that other designers may use as they see fit.
*
* To make an EDIF file from the sqrt32 module, execute the command:
*
* iverilog -osqrt32.edf -tfpga -parch=virtex sqrt-virtex.v
*
* The -parch=virtex tells the code generator to generate code for the
* virtex architecture family (we don't yet care what specific part)
* and the -osqrt32.edf places the output into the file
* sqrt32.edf.
*
* Without any preprocessor directives, the only module is the sqrt32
* module, so sqrt32 is compiled as the root. The ports of the module
* are automatically made into ports of the sqrt32.edf netlist, and
* the contents of the sqrt32 module are connected approprately.
*
* COMPLETE CHIP DESIGNS
*
* To make a complete chip design, there are other bits that need to
* be accounted for. Signals must be assigned to pins, and some
* special devices may need to be created. We also want to write into
* the EDIF file complete part information so that the implementation
* tools know how to route the complete design. The command to compile
* for our target part is:
*
* iverilog -ochip.edf -tfpga \
* -parch=virtex -ppart=XC2S15-VQ100 \
* -DMAKE_CHIP=1 sqrt-virtex.v
*
* This command uses the "chip" module as the root. This module in
* turn has ports that are destined to be the pins of the completed
* part. The -ppart= option gives complete part information, that is
* in turn written into the EDIF file. This saves us the drudgery of
* repeating that part number for later commands.
*
* The next steps involve Xilinx software, and to talk to Xilinx
* software, the netlist must be in the form of an "ngd" file, a
* binary netlist format. The command:
*
* ngdbuild chip.edf chip.ngd
*
* does the trick. The input to ngdbuild is the chip.edf file created
* by Icarus Verilog, and the output is the chip.ngd file that the
* implementation tools may read. From this point, it is best to refer
* to Xilinx documentation for the software you are using, but the
* quick summary is:
*
* map -o map.ncd chip.ngd
* par -w map.ncd chip.ncd
*
* The result of this sequence of commands is the chip.ncd file that
* is ready to be viewed by FPGA Edit, or converted to a bit stream,
* or whatever.
*
* POST MAP SIMULATION
*
* Warm fuzzies are good, and retesting your design after the part
* is mapped by the Xilinx backend tools is a cheap source of fuzzies.
* The command to make a Verilog file out of the mapped design is:
*
* ngd2ver chip.ngd chip_root.v
*
* This command creates from the chip.ngd the file "chip_root.v" that
* contains Verilog code that simulates the mapped design. This output
* Verilog has the single root module "chip_root", which came from the
* name of the root module when we were making the EDIF file in the
* first place. The module has ports named just line the ports of the
* chip_root module below.
*
* The generated Verilog uses the library in the directory
* $(XILINX)/verilog/src/simprims. This directory comes with the ISE
* WebPACK installation that you are using. Icarus Verilog is able to
* simulate using that library.
*
* To compile a post-map simulation of the chip_root.v, use the
* command:
*
* iverilog -DSIMULATE -DPOST_MAP -ob.out \
* -y $(XILINX)/verilog/src/simprims \
* sqrt-virtex.v chip_root.v \
* $(XILINX)/verilog/src/glbl.v
*
* This command line generates b.out from the source files
* sqrt-virtex.v and chip_root.v (the latter from ngd2ver)
* and the "-y <path>" flag specifies the library directory that will
* be needed. The glbl.v source file is also included to provide the
* GSR and related signals.
*
* The POST_MAP compiler directive causes the GSR manipulations
* included in the test bench to be compiled in, to simulate the chip
* startup. Other then that, the test bench runs the post-map design
* the same way the pre-synthesis design works.
*
* Run this design with the command:
*
* vvp b.out
*
* And there you go.
*/
`ifndef POST_MAP
/*
* This module approximates the square root of an unsigned 32bit
* number. The algorithm works by doing a bit-wise binary search.
* Starting from the most significant bit, the accumulated value
* tries to put a 1 in the bit position. If that makes the square
* too big for the input, the bit is left zero, otherwise it is set
* in the result. This continues for each bit, decreasing in
* significance, until all the bits are calculated or all the
* remaining bits are zero.
*
* Since the result is an integer, this function really calculates
* value of the expression:
*
* x = floor(sqrt(y))
*
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32 bit numbers, this will never run more than 16 iterations,
* which amounts to 16 clocks.
*/
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] acc;
// acc holds the accumulated result, and acc2 is the accumulated
// square of the accumulated result.
reg [15:0] acc;
reg [31:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [31:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc, and guess2 holds
// the square of that guess. The guess2 calculation is a little bit
// subtle. The idea is that:
//
// guess2 = (acc + bit) * (acc + bit)
// = (acc * acc) + 2*acc*bit + bit*bit
// = acc2 + 2*acc*bit + bit2
// = acc2 + 2 * (acc<<bitl) + bit
//
// This works out using shifts because bit and bit2 are known to
// have only a single bit in them.
wire [15:0] guess = acc | bit;
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
(* ivl_synthesis_on *)
always @(posedge clk or posedge reset)
if (reset) begin
acc = 0;
acc2 = 0;
bitl = 15;
end else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 5'd1;
end
endmodule // sqrt32
`endif // `ifndef POST_MAP
`ifdef SIMULATE
/*
* This module is a test bench for the sqrt32 module. It runs some
* test input values through the sqrt32 module, and checks that the
* output is valid. If an invalid output is generated, print and
* error message and stop immediately. If all the tested values pass,
* then print PASSED after the test is complete.
*/
module main;
reg [31:0] x;
reg clk, reset;
wire [15:0] y;
wire rdy;
`ifdef POST_MAP
chip_root dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
`else
sqrt32 dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
`endif
(* ivl_synthesis_off *)
always #5 clk = !clk;
task reset_dut;
begin
reset = 1;
@(posedge clk) ;
#1 reset = 0;
@(negedge clk) ;
end
endtask // reset_dut
task crank_dut;
begin
while (rdy == 0) begin
@(posedge clk) /* wait */;
end
end
endtask // crank_dut
`ifdef POST_MAP
reg GSR;
assign glbl.GSR = GSR;
`endif
integer idx;
(* ivl_synthesis_off *)
initial begin
reset = 0;
clk = 0;
/* If doing a post-map simulation, when we need to wiggle
The GSR bit to simulate chip power-up. */
`ifdef POST_MAP
GSR = 1;
#100 GSR = 0;
`endif
#100 x = 1;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
x = 3;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
x = 4;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
for (idx = 0 ; idx < 200 ; idx = idx + 1) begin
x = $random;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
if (x < (y * y)) begin
$display("ERROR: y is too big");
$finish;
end
if (x > ((y + 1)*(y + 1))) begin
$display("ERROR: y is too small");
$finish;
end
end
$display("PASSED");
$finish;
end
endmodule // main
`endif
`ifdef MAKE_CHIP
/*
* This module represents the chip packaging that we intend to
* generate. We bind pins here, and route the clock to the global
* clock buffer.
*/
module chip_root(clk, rdy, reset, x, y);
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] y;
wire clk_int;
(* cellref="BUFG:O,I" *)
buf gbuf (clk_int, clk);
sqrt32 dut(.clk(clk_int), .reset(reset), .rdy(rdy), .x(x), .y(y));
/* Assign the clk to GCLK0, which is on pin P39. */
$attribute(clk, "PAD", "P39");
// We don't care where the remaining pins go, so set the pin number
// to 0. This tells the implementation tools that we want a PAD,
// but we don't care which. Also note the use of a comma (,)
// separated list to assign pins to the bits of a vector.
$attribute(rdy, "PAD", "0");
$attribute(reset, "PAD", "0");
$attribute(x, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
$attribute(y, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
endmodule // chip_root
`endif
+6 -6
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $"
* $Id: sqrt.vl,v 1.3 2000/11/04 01:53:24 steve Exp $"
*/
/*
@@ -50,7 +50,7 @@
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32 bit numbers, this will never run more than 16 iterations,
* For 32bit numbers, this will never run more then 16 iterations,
* which amounts to 16 clocks.
*/
@@ -97,8 +97,8 @@ module sqrt32(clk, rdy, reset, x, .y(acc));
bitl = 15;
end
endtask
initial clear;
initial clear;
always @(reset or posedge clk)
if (reset)
@@ -121,14 +121,14 @@ module main;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always @(posedge rdy) begin
$display("sqrt(%d) --> %d", value, result);
$finish;
end
initial begin
clk = 0;
+2 -2
View File
@@ -72,8 +72,8 @@ module main;
// These attribute commands assign pins to the listed wires.
// This can be done to wires and registers, as internally both
// are treated as named signals. It doesn't work (yet) on vectors,
// though, so break out the vectors with scalar assignments.
// though, so break out the vectors with scaler assignments.
assign a[0] = a0;
assign a[1] = a1;
assign a[2] = a2;
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright (c) 1999 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
*/
// This example describes a 16x1 RAM that can be synthesized into
// a CLB ram in a Xilinx FPGA.
module ram16x1 (q, d, a, we, wclk);
output q;
input d;
input [3:0] a;
input we;
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
endmodule /* ram16x1 */
module main;
wire q;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
$monitor("q = %b", q);
d = 0;
wclk = 0;
a = 5;
we = 1;
#1 wclk = 1;
#1 wclk = 0;
end
endmodule /* main */
+294 -636
View File
File diff suppressed because it is too large Load Diff
-84
View File
@@ -1,84 +0,0 @@
Icarus Verilog Extensions
Icarus Verilog supports certain extensions to the baseline IEEE1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, and some are expressions of internal
behavior of Icarus Verilog, made available as a tool debugging aid.
* Builtin System Functions
** Extended Verilog Data Types
This feature is turned off if the generation flag "-g" is set to other
then the default "2x". For example, "iverilog -g2x" enables extended
data types, and "iverilog -g2" disables them.
Icarus Verilog adds support for extended data types. This extended
type syntax is based on a proposal by Cadence Design Systems,
originally as an update to the IEEE1364. That original proposal has
apparently been absorbed by the IEEE1800 SystemVerilog
standard. Icarus Verilog currently only takes the new primitive types
from the proposal.
Extended data types separates the concept of net/variable from the
data type. Both nets and variables can declared with any data
type. The primitive types available are:
logic - The familiar 0, 1, x and z, optionally with strength.
bool - Limited to only 0 and 1
real - 64bit real values
Nets with logic type may have multiple drivers with strength, and the
value is resolved the usual way. Only logic values may be driven to
logic nets, so bool values driven onto logic nets are implicitly
converted to logic.
Nets with any other type may not have multiple drivers. The compiler
should detect the multiple drivers and report an error.
- Declarations
The declaration of a net is extended to include the type of the wire,
with the syntax:
wire <type> <wire-assignment-list>... ;
The <type>, if omitted, is taken to be logic. The "wire" can be any of
the net keywords. Wires can be logic, bool, real, or vectors of logic
or bool. Some valid examples:
wire real foo = 1.0;
tri logic bus[31:0];
wire bool addr[23:0];
... and so on.
The declarations of variables is similar. The "reg" keyword is used to
specify that this is a variable. Variables can have the same data
types as nets.
- Ports
Module and task ports in standard verilog are restricted to logic
types. This extension removes that restriction, allowing any type to
pass through the port consistent with the continuous assignment
connectivity that is implied by the type.
- Expressions
Expressions in the face of real values is covered by the baseline
Verilog standard.
The bool type supports the same operators as the logic type, with the
obvious differences imposed by the limited domain.
Comparison operators (not case compare) return logic if either of
their operands is logic. If both are bool or real (including mix of
bool and real) then the result is bool. This is because comparison of
bools and reals always return exactly true or false.
Case comparison returns bool. This differs from baseline Verilog,
which strictly speaking returns a logic, but only 0 or 1 values.
All the arithmetic operators return bool if both of their operands are
bool or real. Otherwise, they return logic.

Some files were not shown because too many files have changed in this diff Show More