mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 14:27:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6854660e18 | ||
|
|
6818d996ea | ||
|
|
4907776eaa | ||
|
|
51dd41f81a | ||
|
|
e4ae832153 | ||
|
|
b3a3428b9a | ||
|
|
2abdcfcaa4 | ||
|
|
526b87cae3 | ||
|
|
9383b165a4 | ||
|
|
e827f8f8c1 | ||
|
|
965d928430 | ||
|
|
96936456da | ||
|
|
94647be1f0 | ||
|
|
e45230061e | ||
|
|
180bfc5e72 | ||
|
|
6d40326a2f | ||
|
|
0a630b60dd | ||
|
|
1e4ffc292d | ||
|
|
a579114ae2 | ||
|
|
8dfe16f6d2 | ||
|
|
d1dac0017d | ||
|
|
5e627c9adc | ||
|
|
98ba641e67 | ||
|
|
a70dd79cd8 | ||
|
|
a8ee786036 | ||
|
|
d16e8f7c94 | ||
|
|
4148a2a44c | ||
|
|
5f38591676 | ||
|
|
c10e572091 | ||
|
|
1ab8879100 | ||
|
|
2d498363d7 | ||
|
|
15059bbfdc | ||
|
|
9de786fc44 | ||
|
|
62cffe16f4 | ||
|
|
d3eb53e6b1 | ||
|
|
b631e6e704 | ||
|
|
ba3790dc2b | ||
|
|
f02f5be3cc | ||
|
|
7f67afe9d5 | ||
|
|
d76ad25778 | ||
|
|
21ba781604 | ||
|
|
95c8115fc7 | ||
|
|
49366d1334 | ||
|
|
e2b94947f5 | ||
|
|
efe05a77cb | ||
|
|
8bf434754f | ||
|
|
491df9c327 | ||
|
|
fca2e64808 | ||
|
|
6cd7c1a650 | ||
|
|
3dbc07f34d | ||
|
|
57b8ca191f | ||
|
|
9ee0210cac | ||
|
|
69cfdbdc54 | ||
|
|
76c0fe459c | ||
|
|
9ba1177a4d | ||
|
|
51fd249d8a | ||
|
|
050ec6f325 | ||
|
|
03d7448550 | ||
|
|
b3529d8593 | ||
|
|
112368c7de | ||
|
|
d1f0a0b0d7 | ||
|
|
b043445c80 | ||
|
|
fd371a3958 | ||
|
|
35619771dd | ||
|
|
bdc6cb8723 | ||
|
|
2d63705093 | ||
|
|
b108167441 | ||
|
|
9949040285 | ||
|
|
e8e0cd7cab | ||
|
|
f2d4966634 | ||
|
|
50bf2095df | ||
|
|
2003c5a21e | ||
|
|
bfd393c91c | ||
|
|
37ae777111 | ||
|
|
dd69872266 | ||
|
|
fbfc796647 | ||
|
|
8d3102388b | ||
|
|
ba309e60bb | ||
|
|
5472b27e1f | ||
|
|
e7fa56981a | ||
|
|
55ba131997 | ||
|
|
559f73c135 | ||
|
|
b97f9448e0 | ||
|
|
a7ae8adf9b | ||
|
|
896f1b0de1 | ||
|
|
ca55cadc6c | ||
|
|
324ba713e5 | ||
|
|
69ebd0c49e | ||
|
|
d60112d58b | ||
|
|
5807d6912e | ||
|
|
ec0e35b940 | ||
|
|
c8d67b904a | ||
|
|
c55adddb69 | ||
|
|
8e63f56caf | ||
|
|
9e223b9696 | ||
|
|
dd7472d125 | ||
|
|
0ef1ecab5e | ||
|
|
28719e8584 | ||
|
|
a0ed5e9e29 | ||
|
|
20b7a23bde | ||
|
|
33783385d2 | ||
|
|
914746f6f3 | ||
|
|
c6453a0854 | ||
|
|
413932e406 | ||
|
|
9531920685 | ||
|
|
4456937274 | ||
|
|
efef8fba85 | ||
|
|
177b6ffb6a | ||
|
|
1295058e5d | ||
|
|
b5b02269f1 | ||
|
|
60adfb845d | ||
|
|
a4c5ff0bd3 | ||
|
|
72f9dc5094 | ||
|
|
65f09337f6 | ||
|
|
8d2858c555 | ||
|
|
89acc41437 | ||
|
|
536068bdfb | ||
|
|
2d7380c03b | ||
|
|
27af95d402 | ||
|
|
17c891bc9c | ||
|
|
38ec4b7851 | ||
|
|
6f9ebb1e60 | ||
|
|
0fd5a79760 | ||
|
|
4288f3c6d0 | ||
|
|
d64295ed65 | ||
|
|
2f8a40b159 | ||
|
|
081a6a4088 | ||
|
|
c971448760 | ||
|
|
c275ef9482 | ||
|
|
8188c4c690 | ||
|
|
d482e341ae | ||
|
|
f2b9b8946f | ||
|
|
fa4a873628 | ||
|
|
a436bfc711 | ||
|
|
c2ab27541f | ||
|
|
5160021b48 | ||
|
|
f349449a49 | ||
|
|
de7f87853d | ||
|
|
6a02613fca | ||
|
|
3bb408faf2 | ||
|
|
4987970af4 | ||
|
|
d98720af4d | ||
|
|
793493d3ff | ||
|
|
36785997cb | ||
|
|
923a3ea537 | ||
|
|
8aca824c0f | ||
|
|
e6b25a4e20 | ||
|
|
d98b7ffb2e | ||
|
|
e617e4a98c | ||
|
|
1970e41041 | ||
|
|
e331b182a7 | ||
|
|
11b0cc5bf3 | ||
|
|
5b0c7be6b7 | ||
|
|
59ac435c71 | ||
|
|
57c3e86084 | ||
|
|
f0e0377a20 | ||
|
|
ae3198b505 | ||
|
|
d4525ddc16 | ||
|
|
19e8a92729 | ||
|
|
1bd1d287e4 | ||
|
|
4c8c14ceec | ||
|
|
df968687e4 |
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -36,25 +36,8 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Attrib::copy_attributes(const map<string,verinum>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,verinum>::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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const verinum& Attrib::attribute(const string&key) const
|
||||
const verinum& Attrib::attribute(perm_string key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -66,7 +49,7 @@ const verinum& Attrib::attribute(const string&key) const
|
||||
return null;
|
||||
}
|
||||
|
||||
void Attrib::attribute(const string&key, const verinum&value)
|
||||
void Attrib::attribute(perm_string key, const verinum&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -108,10 +91,10 @@ unsigned Attrib::attr_cnt() const
|
||||
return nlist_;
|
||||
}
|
||||
|
||||
const char* Attrib::attr_key(unsigned idx) const
|
||||
perm_string Attrib::attr_key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key.c_str();
|
||||
return list_[idx].key;
|
||||
}
|
||||
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
@@ -123,6 +106,9 @@ 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.
|
||||
*
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.h,v 1.4 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "StringHeap.h"
|
||||
# include "verinum.h"
|
||||
|
||||
/*
|
||||
@@ -35,20 +35,20 @@ class Attrib {
|
||||
Attrib();
|
||||
~Attrib();
|
||||
|
||||
const verinum&attribute(const string&key) const;
|
||||
void attribute(const string&key, const verinum&value);
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
bool has_compat_attributes(const Attrib&that) const;
|
||||
|
||||
|
||||
/* Provide a means of iterating over the entries in the map. */
|
||||
unsigned attr_cnt() const;
|
||||
const char* attr_key(unsigned idx) const;
|
||||
perm_string attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
string key;
|
||||
perm_string key;
|
||||
verinum val;
|
||||
};
|
||||
|
||||
@@ -62,6 +62,9 @@ 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.
|
||||
*
|
||||
|
||||
+21
-29
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.160 2003/11/26 01:36:55 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.169 2004/10/13 22:01:34 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.7
|
||||
VERSION = 0.8
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -43,7 +43,6 @@ mandir = @mandir@
|
||||
libdir64 = @libdir64@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
@@ -56,23 +55,20 @@ STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
||||
CXXFLAGS = -Wall @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
# 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
|
||||
|
||||
all: dep ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub; \
|
||||
for dir in ivlpp tgt-verilog tgt-stub; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) $@
|
||||
|
||||
@@ -82,20 +78,14 @@ ifeq (@WIN32@,yes)
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
endif
|
||||
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
|
||||
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'
|
||||
|
||||
clean:
|
||||
@@ -103,7 +93,7 @@ clean:
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
|
||||
rm -rf dep ivl@EXEEXT@
|
||||
|
||||
@@ -126,7 +116,7 @@ net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o symbol_search.o sync.o \
|
||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
@@ -143,19 +133,21 @@ ifeq (@WIN32@,yes)
|
||||
# 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) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
|
||||
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;@INCLUDEDIR@;@includedir@;' \
|
||||
@@ -169,7 +161,7 @@ dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.cc
|
||||
$(CXX) -Wall @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
@@ -209,7 +201,7 @@ INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
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
|
||||
@@ -259,7 +251,7 @@ $(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MINGW32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.cc,v 1.21 2003/04/02 03:00:14 steve Exp $"
|
||||
#ident "$Id: Module.cc,v 1.25 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -28,9 +28,10 @@
|
||||
# include <assert.h>
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(const char*n)
|
||||
Module::Module(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
default_nettype = NetNet::NONE;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
@@ -42,12 +43,12 @@ void Module::add_gate(PGate*gate)
|
||||
gates_.push_back(gate);
|
||||
}
|
||||
|
||||
void Module::add_task(const string&name, PTask*task)
|
||||
void Module::add_task(perm_string name, PTask*task)
|
||||
{
|
||||
tasks_[name] = task;
|
||||
}
|
||||
|
||||
void Module::add_function(const string &name, PFunction *func)
|
||||
void Module::add_function(perm_string name, PFunction *func)
|
||||
{
|
||||
funcs_[name] = func;
|
||||
}
|
||||
@@ -75,7 +76,7 @@ unsigned Module::port_count() const
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
@@ -88,7 +89,7 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
return zero;
|
||||
}
|
||||
|
||||
unsigned Module::find_port(const string&name) const
|
||||
unsigned Module::find_port(const char*name) const
|
||||
{
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
@@ -118,7 +119,7 @@ PWire* Module::get_wire(const hname_t&name) const
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
PGate* Module::get_gate(const string&name)
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
for (list<PGate*>::iterator cur = gates_.begin()
|
||||
; cur != gates_.end()
|
||||
@@ -149,6 +150,18 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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
|
||||
@@ -19,16 +19,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.32 2003/06/20 00:53:19 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.37 2004/06/13 04:56:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
# include "netlist.h"
|
||||
class PData;
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
@@ -56,16 +57,17 @@ class Module : public LineInfo {
|
||||
the port. */
|
||||
public:
|
||||
struct port_t {
|
||||
string name;
|
||||
perm_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(const char*name);
|
||||
explicit Module(perm_string name);
|
||||
~Module();
|
||||
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
@@ -76,14 +78,14 @@ class Module : public LineInfo {
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
};
|
||||
map<string,param_expr_t>parameters;
|
||||
map<string,param_expr_t>localparams;
|
||||
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<string,PExpr*>specparams;
|
||||
map<perm_string,PExpr*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
@@ -97,25 +99,25 @@ 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<string> param_names;
|
||||
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;
|
||||
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
/* Keep a table of datum variables declared in the module. */
|
||||
map<hname_t,PData*>datum;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
const char*mod_name() const { return name_; }
|
||||
perm_string mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
||||
@@ -125,17 +127,17 @@ class Module : public LineInfo {
|
||||
PWire* add_wire(PWire*wire);
|
||||
|
||||
void add_behavior(PProcess*behave);
|
||||
void add_task(const string&name, PTask*def);
|
||||
void add_function(const string&name, PFunction*def);
|
||||
void add_task(perm_string name, PTask*def);
|
||||
void add_function(perm_string name, PFunction*def);
|
||||
|
||||
unsigned port_count() const;
|
||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const string&) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Find a wire by name. This is used for connecting gates to
|
||||
// existing wires, etc.
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PGate* get_gate(const string&name);
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
@@ -149,13 +151,13 @@ class Module : public LineInfo {
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
perm_string name_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<string,PTask*> tasks_;
|
||||
map<string,PFunction*> funcs_;
|
||||
map<perm_string,PTask*> tasks_;
|
||||
map<perm_string,PFunction*> funcs_;
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
@@ -165,6 +167,21 @@ class Module : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.37 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.36 2004/05/25 19:21:06 steve
|
||||
* More identifier lists use perm_strings.
|
||||
*
|
||||
* Revision 1.35 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.34 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.33 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.32 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 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
|
||||
@@ -17,14 +17,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const char*n)
|
||||
PEvent::PEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
@@ -33,13 +33,16 @@ PEvent::~PEvent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* PEvent::name() const
|
||||
perm_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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-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
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.8 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
class Design;
|
||||
@@ -36,16 +37,17 @@ class NetScope;
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string.
|
||||
explicit PEvent(const char*name);
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the event, without any scope.
|
||||
explicit PEvent(perm_string name);
|
||||
~PEvent();
|
||||
|
||||
const char* name() const;
|
||||
perm_string name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
@@ -54,6 +56,9 @@ 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
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.33 2003/01/27 05:09:17 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.35 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -67,12 +67,12 @@ bool PEBinary::is_constant(Module*mod) const
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
{
|
||||
}
|
||||
@@ -161,13 +161,19 @@ bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
if (mod == 0) return false;
|
||||
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(path_.peek_name(0));
|
||||
/* This is a work-around for map not matching < even when
|
||||
there is a perm_string operator that can do the comprare.
|
||||
|
||||
The real fix is to make the path_ carry perm_strings. */
|
||||
perm_string tmp = perm_string::literal(path_.peek_name(0));
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(tmp);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(tmp);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
@@ -256,6 +262,12 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.65 2003/02/08 19:49:21 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.66 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -160,7 +160,7 @@ class PEEvent : public PExpr {
|
||||
|
||||
edge_t type() const;
|
||||
PExpr* expr() const;
|
||||
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -492,6 +492,9 @@ class PECallFunction : public PExpr {
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* 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
|
||||
|
||||
+11
-6
@@ -17,16 +17,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
: out_(0), ports_(0), statement_(0)
|
||||
PFunction::PFunction(perm_string name)
|
||||
: name_(name), ports_(0), statement_(0)
|
||||
{
|
||||
return_type_.type = PTF_NONE;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
@@ -46,14 +47,18 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::set_output(PWire*o)
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
{
|
||||
assert(out_ == 0);
|
||||
out_ = o;
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.cc,v 1.15 2003/03/06 04:37:12 steve Exp $"
|
||||
#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -27,7 +27,7 @@
|
||||
# include "verinum.h"
|
||||
# include <assert.h>
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -37,7 +37,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -47,7 +47,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name, svector<PExpr*>*pins)
|
||||
PGate::PGate(perm_string name, svector<PExpr*>*pins)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
str0_ = STRONG;
|
||||
@@ -99,13 +99,13 @@ void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
: PGate("", pins)
|
||||
: PGate(perm_string(), pins)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
|
||||
: PGate("", pins, dels)
|
||||
: PGate(perm_string(), pins, dels)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
@@ -114,14 +114,14 @@ PGAssign::~PGAssign()
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
@@ -142,14 +142,14 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
|
||||
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const char*type, const string&name,
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
@@ -184,13 +184,16 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGModule::get_type()
|
||||
perm_string PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.25 2003/03/06 04:37:12 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PDelays.h"
|
||||
@@ -49,21 +50,21 @@ class Module;
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public LineInfo {
|
||||
|
||||
|
||||
public:
|
||||
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins);
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
|
||||
const string& get_name() const { return name_; }
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
@@ -79,7 +80,7 @@ class PGate : public LineInfo {
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -87,13 +88,13 @@ class PGate : public LineInfo {
|
||||
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:
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
PDelays delay_;
|
||||
svector<PExpr*>*pins_;
|
||||
|
||||
@@ -141,10 +142,10 @@ class PGBuiltin : public PGate {
|
||||
TRANIF1, RTRANIF0, RTRANIF1 };
|
||||
|
||||
public:
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
@@ -171,17 +172,16 @@ class PGBuiltin : public PGate {
|
||||
class PGModule : public PGate {
|
||||
|
||||
public:
|
||||
// NOTE: The type parameter to all the constructors is assumed
|
||||
// to have been permallocated.
|
||||
// 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(const char*type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_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(const char*type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
|
||||
@@ -203,10 +203,10 @@ class PGModule : public PGate {
|
||||
|
||||
// This returns the module name of this module. It is a
|
||||
// permallocated string.
|
||||
const char* get_type();
|
||||
perm_string get_type();
|
||||
|
||||
private:
|
||||
const char* type_;
|
||||
perm_string type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
@@ -227,6 +227,18 @@ class PGModule : public PGate {
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -19,16 +19,32 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 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_INTEGER,
|
||||
PTF_REAL,
|
||||
PTF_REALTIME,
|
||||
PTF_TIME
|
||||
};
|
||||
|
||||
struct PTaskFuncArg {
|
||||
PTaskFuncEnum type;
|
||||
svector<PExpr*>*range;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
@@ -69,16 +85,18 @@ 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();
|
||||
explicit PFunction(perm_string name);
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_output(PWire*);
|
||||
void set_return(PTaskFuncArg t);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -91,13 +109,19 @@ class PFunction : public LineInfo {
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
PWire*out_;
|
||||
perm_string name_;
|
||||
PTaskFuncArg return_type_;
|
||||
svector<PWire *> *ports_;
|
||||
Statement *statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
* 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
|
||||
@@ -17,18 +17,35 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.cc,v 1.1 2003/07/15 05:07:13 steve Exp $"
|
||||
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PUdp.h"
|
||||
|
||||
PUdp::PUdp(const string&n, unsigned nports)
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.10 2003/07/15 05:07:13 steve Exp $"
|
||||
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include "verinum.h"
|
||||
|
||||
@@ -52,9 +53,11 @@ class PExpr;
|
||||
class PUdp {
|
||||
|
||||
public:
|
||||
explicit PUdp(const string&n, unsigned nports);
|
||||
explicit PUdp(perm_string n, unsigned nports);
|
||||
|
||||
svector<string>ports;
|
||||
unsigned find_port(const char*name);
|
||||
|
||||
bool sequential;
|
||||
|
||||
svector<string>tinput;
|
||||
@@ -67,7 +70,7 @@ class PUdp {
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
@@ -77,6 +80,12 @@ 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.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.16 2003/01/30 16:23:07 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.17 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -69,7 +69,7 @@ class PWire : public LineInfo {
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
@@ -100,6 +100,9 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+2
-2
@@ -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 ;
|
||||
|
||||
+21
-11
@@ -1,5 +1,5 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2003 Stephen Williams
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
@@ -9,7 +9,7 @@ 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
|
||||
@@ -296,8 +296,8 @@ Example: Compiling "hello.vl"
|
||||
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
@@ -307,7 +307,7 @@ endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
@@ -334,8 +334,8 @@ 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 compiler presumes that
|
||||
they return 32 bits. This is the typical case.
|
||||
- System functions are supported, but the return value is a little
|
||||
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
|
||||
|
||||
- Specify blocks are parsed but ignored in general.
|
||||
|
||||
@@ -344,9 +344,6 @@ constructs.
|
||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||
and rtranif0 are not supported.
|
||||
|
||||
- Module instance arrays are not supported, although gate instance
|
||||
arrays do work.
|
||||
|
||||
- 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;"
|
||||
@@ -364,6 +361,11 @@ IEEE1364 standard, but have well defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined.
|
||||
|
||||
$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
|
||||
@@ -387,6 +389,14 @@ language that are defined.
|
||||
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
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -86,7 +86,7 @@ PAssignNB::~PAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
|
||||
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
|
||||
: name_(n), bl_type_(t), list_(st)
|
||||
{
|
||||
}
|
||||
@@ -295,6 +295,9 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+11
-4
@@ -19,11 +19,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.h,v 1.38 2003/05/19 02:50:58 steve Exp $"
|
||||
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "HName.h"
|
||||
@@ -56,7 +57,7 @@ class PProcess : public LineInfo {
|
||||
Type type() const { return type_; }
|
||||
Statement*statement() { return statement_; }
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -148,7 +149,7 @@ class PBlock : public Statement {
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
|
||||
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
@@ -161,7 +162,7 @@ class PBlock : public Statement {
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
perm_string name_;
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
};
|
||||
@@ -455,6 +456,12 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+63
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.cc,v 1.5 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
@@ -64,6 +64,11 @@ const char* StringHeap::add(const char*text)
|
||||
return res;
|
||||
}
|
||||
|
||||
perm_string StringHeap::make(const char*text)
|
||||
{
|
||||
return perm_string(add(text));
|
||||
}
|
||||
|
||||
|
||||
StringHeapLex::StringHeapLex()
|
||||
{
|
||||
@@ -121,8 +126,64 @@ const char* StringHeapLex::add(const char*text)
|
||||
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
|
||||
|
||||
+47
-2
@@ -1,7 +1,7 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
|
||||
* 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
|
||||
@@ -19,9 +19,48 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.h,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: StringHeap.h,v 1.5 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include <string>
|
||||
|
||||
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
|
||||
@@ -34,6 +73,7 @@ class StringHeap {
|
||||
~StringHeap();
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
@@ -60,6 +100,8 @@ class StringHeapLex : private StringHeap {
|
||||
~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;
|
||||
@@ -78,6 +120,9 @@ class StringHeapLex : private StringHeap {
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.h,v $
|
||||
* 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
|
||||
|
||||
+7
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: acc_user.h,v 1.19 2003/10/10 02:57:45 steve Exp $"
|
||||
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -195,6 +195,7 @@ extern void acc_close(void);
|
||||
* 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);
|
||||
@@ -258,6 +259,8 @@ 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);
|
||||
|
||||
@@ -272,6 +275,9 @@ 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.
|
||||
*
|
||||
|
||||
Vendored
+140
-2
@@ -14,7 +14,7 @@
|
||||
AC_DEFUN([AX_CPP_IDENT],
|
||||
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
||||
[AC_TRY_COMPILE([
|
||||
#ident "$Id: aclocal.m4,v 1.1 2003/11/08 19:27:50 steve Exp $"
|
||||
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
|
||||
],[while (0) {}],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
||||
@@ -47,7 +47,7 @@ AC_DEFUN([AX_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; then
|
||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_LEADING
|
||||
@@ -67,3 +67,141 @@ if test $ax_cv_c_underscores_trailing = yes; then
|
||||
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
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: async.cc,v 1.5 2003/09/04 20:28:05 steve Exp $"
|
||||
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -36,6 +36,16 @@ 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
|
||||
@@ -64,6 +74,9 @@ bool NetEvWait::is_asynchronous()
|
||||
|
||||
delete sense;
|
||||
delete inputs;
|
||||
|
||||
/* If it passes all the other tests, then this statement is
|
||||
asynchronous. */
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,6 +95,12 @@ bool NetProcTop::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.
|
||||
*
|
||||
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
echo "Autoconf in root..."
|
||||
autoconf
|
||||
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga libveriuser cadpli
|
||||
for dir in vpip vpi vvp tgt-vvp tgt-fpga libveriuser cadpli
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd ./$dir ; autoconf )
|
||||
( cd ./$dir ; autoconf --include=.. )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
|
||||
+6
-7
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.8 2003/11/08 19:30:15 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.11 2004/10/04 01:09:07 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -38,13 +38,12 @@ vpidir = @libdir@/ivl/@vpidir1@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
STRIP = @STRIP@
|
||||
|
||||
@@ -69,21 +68,21 @@ dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -Wall -I$(srcdir) -I$(srcdir)/.. -I.. $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
mv $*.d dep
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@WIN32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += -liberty
|
||||
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
|
||||
rm -rf *.o dep cadpli.vpl bin32
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
|
||||
+8
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cadpli.c,v 1.5 2003/08/26 16:26:02 steve Exp $"
|
||||
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vpi_user.h>
|
||||
@@ -37,7 +37,7 @@ static void thunker_register(void)
|
||||
struct t_vpi_vlog_info vlog_info;
|
||||
void*mod;
|
||||
void*boot;
|
||||
void*tf;
|
||||
struct t_tfcell*tf;
|
||||
int idx;
|
||||
|
||||
vpi_get_vlog_info(&vlog_info);
|
||||
@@ -91,6 +91,12 @@ void (*vlog_startup_routines[])() = {
|
||||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
||||
+14
-161
@@ -4,11 +4,12 @@ AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# vvp32 is by default disabled
|
||||
@@ -34,180 +35,32 @@ AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
# Compiler option for position independent code, needed whan making shared objects.
|
||||
AX_C_PICFLAG
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
AC_MSG_CHECKING("for flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
|
||||
# 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. VPI support requires this.
|
||||
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"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
|
||||
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_MSG_CHECKING("for extra libs needed")
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
EXTRALIBS="-liberty"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
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.
|
||||
#######################
|
||||
|
||||
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 "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; 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")
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
|
||||
|
||||
AC_MSG_CHECKING("for ident support in C compiler")
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-machten*)
|
||||
ident_support=
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(ident_support)
|
||||
AC_MSG_RESULT($ident_support)
|
||||
AX_CPP_IDENT
|
||||
|
||||
# where to put vpi subdirectories
|
||||
AC_MSG_CHECKING(for VPI subdirectories)
|
||||
|
||||
+16
-4
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.1 2003/02/17 00:01:25 steve Exp $"
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
@@ -48,14 +48,14 @@ inline const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
FormatMessage(
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &msg,
|
||||
sizeof(msg) - 1,
|
||||
NULL
|
||||
NULL
|
||||
);
|
||||
return msg;
|
||||
}
|
||||
@@ -65,7 +65,13 @@ inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
if (sym == 0 && nm[0] == '_')
|
||||
sym = dlsym(dll, nm+1);
|
||||
return sym;
|
||||
}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
@@ -90,6 +96,12 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.3 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.2 2003/12/12 05:43:08 steve
|
||||
* Some systems dlsym requires leading _ or not on whim.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
|
||||
+4
-6
@@ -1,6 +1,4 @@
|
||||
|
||||
# The make check target uses this to check the compilation of the
|
||||
# compiler.
|
||||
|
||||
[-tvvp-check]
|
||||
<ivl>./ivl %[N-N%N] -C%C -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -- -
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=tgt-vvp/vvp.tgt
|
||||
|
||||
+57
-35
@@ -1,7 +1,7 @@
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-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
|
||||
@@ -19,12 +19,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compiler.h,v 1.19 2003/11/13 05:55:33 steve Exp $"
|
||||
#ident "$Id: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <string>
|
||||
# include "netlist.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
@@ -65,7 +65,7 @@
|
||||
/*
|
||||
* 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.
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
@@ -81,6 +81,10 @@ 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;
|
||||
|
||||
/* Path to a directory useful for finding subcomponents. */
|
||||
extern const char*basedir;
|
||||
|
||||
@@ -102,12 +106,60 @@ extern generation_t generation_flag;
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
extern map<string,unsigned> missing_modules;
|
||||
extern map<perm_string,unsigned> missing_modules;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
NetExpr::TYPE 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.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.
|
||||
*
|
||||
@@ -122,35 +174,5 @@ extern StringHeapLex lex_strings;
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.15 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*
|
||||
* Revision 1.14 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.13 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.12 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.11 2002/05/28 00:50:39 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.10 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.9 2002/04/22 00:53:39 steve
|
||||
* Do not allow implicit wires in sensitivity lists.
|
||||
*
|
||||
* Revision 1.8 2002/04/15 00:04:22 steve
|
||||
* Timescale warnings.
|
||||
*
|
||||
* Revision 1.7 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*/
|
||||
#endif
|
||||
|
||||
+5
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: config.h.in,v 1.10 2003/08/26 16:26:01 steve Exp $"
|
||||
#ident "$Id: config.h.in,v 1.11 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -31,7 +31,7 @@
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
# undef NEED_TU
|
||||
# undef WLU
|
||||
# undef WTU
|
||||
# undef HAVE_TIMES
|
||||
@@ -50,6 +50,9 @@
|
||||
|
||||
/*
|
||||
* $Log: config.h.in,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+23
-123
@@ -3,6 +3,7 @@ AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(_pli_types.h)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
@@ -10,9 +11,13 @@ AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable gperf found. ***"
|
||||
echo " Please install the 'gperf' package."
|
||||
exit 1
|
||||
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 ""
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
@@ -31,22 +36,12 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
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)
|
||||
@@ -76,16 +71,6 @@ do_times=no
|
||||
)
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
|
||||
AC_ARG_WITH(ipal,
|
||||
[ --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.
|
||||
@@ -104,107 +89,22 @@ AC_PROG_INSTALL
|
||||
AC_LANG_C
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
AC_MSG_CHECKING("for flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
# Compiler option for position independent code, needed whan making shared objects.
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
# may modify CPPFLAGS and CFLAGS
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
|
||||
|
||||
# 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 $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
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)
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader needs to know this
|
||||
@@ -241,6 +141,6 @@ AC_SUBST(vpidir1)
|
||||
AC_SUBST(vpidir2)
|
||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||
|
||||
AC_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser cadpli)
|
||||
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-fpga libveriuser cadpli)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cprop.cc,v 1.46 2003/11/08 17:53:34 steve Exp $"
|
||||
#ident "$Id: cprop.cc,v 1.47 2004/02/20 18:53:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -56,7 +56,7 @@ 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") != verinum("ADD"))
|
||||
if (obj->attribute(perm_string::literal("LPM_Direction")) != verinum("ADD"))
|
||||
return;
|
||||
|
||||
// If the low bit on the A side is 0, then eliminate it from
|
||||
@@ -1038,6 +1038,9 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.47 2004/02/20 18:53:34 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.46 2003/11/08 17:53:34 steve
|
||||
* Do not remove constants accessible to VPI.
|
||||
*
|
||||
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
|
||||
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)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
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]>
|
||||
|
||||
|
||||
|
||||
|
||||
+43
-5
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.144 2003/07/26 03:34:42 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.149 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -495,6 +495,15 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
|
||||
}
|
||||
|
||||
void NetAssignBase::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
|
||||
n1->dump(o,ind);
|
||||
} else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
|
||||
n2->dump(o,ind);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a block statement */
|
||||
void NetBlock::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
@@ -636,6 +645,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
|
||||
void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "function " << scope_->name() << endl;
|
||||
if (result_sig_)
|
||||
o << setw(ind+2) << "" << "Return signal: "
|
||||
<< result_sig_->name() << endl;
|
||||
if (result_var_)
|
||||
o << setw(ind+2) << "" << "Return variable: "
|
||||
<< result_var_->basename() << endl;
|
||||
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
@@ -677,7 +693,9 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetScope::dump(ostream&o) const
|
||||
{
|
||||
/* This is a constructed hierarchical name. */
|
||||
o << name();
|
||||
|
||||
switch (type_) {
|
||||
case BEGIN_END:
|
||||
o << " sequential block";
|
||||
@@ -689,7 +707,7 @@ void NetScope::dump(ostream&o) const
|
||||
o << " function";
|
||||
break;
|
||||
case MODULE:
|
||||
o << " module <" << (module_name_? module_name_ : "") << ">";
|
||||
o << " module <" << (module_name_? module_name_.str() : "") << ">";
|
||||
break;
|
||||
case TASK:
|
||||
o << " task";
|
||||
@@ -706,7 +724,7 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
/* Dump the parameters for this scope. */
|
||||
{
|
||||
map<string,param_expr_t>::const_iterator pp;
|
||||
map<perm_string,param_expr_t>::const_iterator pp;
|
||||
for (pp = parameters.begin()
|
||||
; pp != parameters.end() ; pp ++) {
|
||||
o << " parameter ";
|
||||
@@ -770,7 +788,10 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
switch (type_) {
|
||||
case FUNC:
|
||||
func_def()->dump(o, 4);
|
||||
if (func_def())
|
||||
func_def()->dump(o, 4);
|
||||
else
|
||||
o << " MISSING FUNCTION DEFINITION" << endl;
|
||||
break;
|
||||
case TASK:
|
||||
task_def()->dump(o, 4);
|
||||
@@ -1043,7 +1064,7 @@ void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->dump(o);
|
||||
|
||||
@@ -1068,6 +1089,23 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.149 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.148 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.147 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.146 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.145 2003/12/17 16:52:39 steve
|
||||
* Debug dumps for synth2.
|
||||
*
|
||||
* Revision 1.144 2003/07/26 03:34:42 steve
|
||||
* Start handling pad of expressions in code generators.
|
||||
*
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.5 2002/12/08 03:06:30 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.7 2004/10/13 22:01:34 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.7
|
||||
VERSION = 0.8
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,14 +37,12 @@ mandir = @mandir@
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog-vpi@EXEEXT@
|
||||
@@ -63,7 +61,7 @@ iverilog-vpi@EXEEXT@: $O
|
||||
|
||||
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -c $(srcdir)/main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
|
||||
# Windows specific...
|
||||
res.o: res.rc
|
||||
|
||||
+565
-565
File diff suppressed because it is too large
Load Diff
+5
-7
@@ -16,12 +16,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.22 2003/11/18 06:31:46 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.24 2004/10/13 22:01:34 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.7
|
||||
VERSION = 0.8
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,14 +37,12 @@ mandir = @mandir@
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -Wall @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I.. -I. -I$(srcdir)/.. -I$(srcdir)
|
||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog@EXEEXT@
|
||||
@@ -70,7 +68,7 @@ cfparse.h cfparse.c: cfparse.y
|
||||
|
||||
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
|
||||
build_string.o: build_string.c globals.h
|
||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cflexor.lex,v 1.7 2003/08/26 16:26:02 steve Exp $"
|
||||
#ident "$Id: cflexor.lex,v 1.8 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
@@ -113,10 +113,10 @@ static int comment_enter;
|
||||
is a little bit tricky, as we don't want to mistake a comment for
|
||||
a string word. */
|
||||
"/"[^\*\/].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
return TOK_STRING; }
|
||||
|
||||
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse_misc.h,v 1.5 2003/09/26 21:25:58 steve Exp $"
|
||||
#ident "$Id: cfparse_misc.h,v 1.6 2004/02/15 18:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -38,10 +38,15 @@ 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.
|
||||
*
|
||||
|
||||
+31
-4
@@ -1,4 +1,4 @@
|
||||
.TH iverilog 1 "$Date: 2003/11/26 01:36:25 $" Version "$Date: 2003/11/26 01:36:25 $"
|
||||
.TH iverilog 1 "$Date: 2004/10/04 01:10:56 $" Version "$Date: 2004/10/04 01:10:56 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
@@ -57,7 +57,7 @@ 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 -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
|
||||
@@ -212,6 +212,33 @@ 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
|
||||
@@ -289,7 +316,7 @@ 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
|
||||
|
||||
@@ -322,5 +349,5 @@ vvp(1),
|
||||
.nf
|
||||
Copyright \(co 2002 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
|
||||
|
||||
+50
-6
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.c,v 1.61 2003/11/18 06:31:46 steve Exp $"
|
||||
#ident "$Id: main.c,v 1.65 2004/06/17 14:47:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -89,6 +89,7 @@ extern const char*optarg;
|
||||
#endif
|
||||
|
||||
# include "globals.h"
|
||||
#include "cfparse_misc.h" /* cfparse() */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
const char sep = '\\';
|
||||
@@ -99,6 +100,7 @@ const char sep = '/';
|
||||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*pbase = 0;
|
||||
const char*mtm = 0;
|
||||
const char*opath = "a.out";
|
||||
const char*npath = 0;
|
||||
@@ -212,7 +214,9 @@ static const char*my_tempfile(const char*str, FILE**fout)
|
||||
static int t_default(char*cmd, unsigned ncmd)
|
||||
{
|
||||
unsigned rc;
|
||||
#ifdef __MINGW32__
|
||||
unsigned ncmd_start = ncmd;
|
||||
#endif
|
||||
|
||||
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
|
||||
rc = strlen(tmp);
|
||||
@@ -364,10 +368,21 @@ void process_define(const char*name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called while processing a file name in a command
|
||||
* file, or a file name on the command line. Look to see if there is a
|
||||
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
|
||||
* is a Verilog source file to be written into the file list.
|
||||
*/
|
||||
void process_file_name(const char*name)
|
||||
{
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
|
||||
fprintf(iconfig_file,"sys_func:%s\n", name);
|
||||
|
||||
} else {
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
int process_generation(const char*name)
|
||||
@@ -477,7 +492,15 @@ int main(int argc, char **argv)
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
base = optarg;
|
||||
/* Undocumented feature: The preprocessor itself
|
||||
may be located at a different location. If the
|
||||
base starts with a 'P', set this special base
|
||||
instead of the main base. */
|
||||
if (optarg[0] == 'P') {
|
||||
pbase = optarg+1;
|
||||
} else {
|
||||
base=optarg;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
command_filename = malloc(strlen(optarg)+1);
|
||||
@@ -567,6 +590,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (pbase == 0)
|
||||
pbase = base;
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
|
||||
printf("Copyright 1998-2003 Stephen Williams\n");
|
||||
@@ -582,6 +608,12 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
||||
/* Tell the core where to find the system.sft. This file
|
||||
describes the system functions so that elaboration knows
|
||||
how to handle them. */
|
||||
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
|
||||
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
fprintf(iconfig_file, "generation:%s\n", generation);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
@@ -624,7 +656,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Start building the preprocess command line. */
|
||||
|
||||
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", base,sep,
|
||||
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", pbase,sep,
|
||||
verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", source_path);
|
||||
|
||||
@@ -689,7 +721,7 @@ int main(int argc, char **argv)
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
|
||||
base, sep,
|
||||
pbase, sep,
|
||||
inc_list? inc_list : "",
|
||||
def_list? def_list : "");
|
||||
|
||||
@@ -703,6 +735,18 @@ int main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.65 2004/06/17 14:47:22 steve
|
||||
* Add a .sft file for the system functions.
|
||||
*
|
||||
* Revision 1.64 2004/03/10 04:51:25 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.63 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.62 2003/12/12 04:36:48 steve
|
||||
* Fix make check to support -tconf configuration method.
|
||||
*
|
||||
* Revision 1.61 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
|
||||
+6
-3
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: substit.c,v 1.4 2002/08/12 01:35:01 steve Exp $"
|
||||
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
@@ -66,7 +66,7 @@ char* substitutions(const char*str)
|
||||
cp += strlen(cp);
|
||||
|
||||
} else {
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 32;
|
||||
buf = realloc(buf, nbuf);
|
||||
@@ -79,7 +79,7 @@ char* substitutions(const char*str)
|
||||
|
||||
/* Add the trailing nul to the string, and reallocate the
|
||||
buffer to be a tight fit. */
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
@@ -96,6 +96,9 @@ char* substitutions(const char*str)
|
||||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
||||
+17
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dup_expr.cc,v 1.16 2003/10/31 02:47:11 steve Exp $"
|
||||
#ident "$Id: dup_expr.cc,v 1.18 2004/06/17 16:06:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -75,6 +75,8 @@ NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, 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());
|
||||
@@ -109,8 +111,13 @@ NetEUFunc* NetEUFunc::dup_expr() const
|
||||
tmp_parms[idx] = parms_[idx]->dup_expr();
|
||||
}
|
||||
|
||||
tmp = new NetEUFunc(func_, result_->dup_expr(), tmp_parms);
|
||||
tmp = 0;
|
||||
if (result_sig_)
|
||||
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
|
||||
if (result_var_)
|
||||
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
|
||||
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -136,6 +143,14 @@ NetEVariable* NetEVariable::dup_expr() const
|
||||
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_anet.cc,v 1.9 2003/09/19 03:50:12 steve Exp $"
|
||||
#ident "$Id: elab_anet.cc,v 1.10 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -157,7 +157,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
cerr << get_line() << ": error: bit/part selects not allowed "
|
||||
<< "on left side of procedural continuous assignment."
|
||||
<< endl;
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -167,6 +167,9 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+114
-47
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_expr.cc,v 1.82 2003/10/09 16:52:52 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.91 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -28,30 +28,6 @@
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
/*
|
||||
* 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;
|
||||
NetExpr::TYPE type;
|
||||
unsigned wid;
|
||||
int signed_flag;
|
||||
};
|
||||
|
||||
static const struct sfunc_return_type sfunc_table[] = {
|
||||
{ "$realtime", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$bitstoreal", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$itor", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$realtobits", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ "$time", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ "$stime", NetExpr::ET_VECTOR, 32, 0 },
|
||||
{ "$simtime", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ 0, NetExpr::ET_VECTOR, 32, 0 }
|
||||
};
|
||||
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": internal error: I do not know how to elaborate"
|
||||
@@ -65,7 +41,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
/*
|
||||
* Elaborate binary expressions. This involves elaborating the left
|
||||
* and right sides, and creating one of a variety of different NetExpr
|
||||
* types.
|
||||
* types.
|
||||
*/
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
@@ -216,6 +192,20 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
sub->cast_signed(true);
|
||||
return sub;
|
||||
}
|
||||
/* add $unsigned to match $signed */
|
||||
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $unsigned() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
sub->cast_signed(false);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Interpret the internal $sizeof system function to return
|
||||
the bit width of the sub-expression. The value of the
|
||||
@@ -245,15 +235,37 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Interpret the internal $is_signed system function to return
|
||||
a single bit flag -- 1 if the expression is signed, 0
|
||||
otherwise. The subexpression is elaborated but not
|
||||
evaluated. */
|
||||
if (strcmp(path_.peek_name(0), "$is_signed") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $is_signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
|
||||
verinum val (sub->has_sign()? verinum::V1 : verinum::V0, 1);
|
||||
delete sub;
|
||||
|
||||
sub = new NetEConst(val);
|
||||
sub->set_line(*this);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Get the return type of the system function by looking it up
|
||||
in the sfunc_table. */
|
||||
unsigned sfunc_idx;
|
||||
for (sfunc_idx = 0 ; sfunc_table[sfunc_idx].name ; sfunc_idx += 1)
|
||||
if (strcmp(path_.peek_name(0), sfunc_table[sfunc_idx].name) == 0)
|
||||
break;
|
||||
const struct sfunc_return_type*sfunc_info
|
||||
= lookup_sys_func(path_.peek_name(0));
|
||||
|
||||
NetExpr::TYPE sfunc_type = sfunc_table[sfunc_idx].type;
|
||||
unsigned wid = sfunc_table[sfunc_idx].wid;
|
||||
NetExpr::TYPE sfunc_type = sfunc_info->type;
|
||||
unsigned wid = sfunc_info->wid;
|
||||
|
||||
|
||||
/* How many parameters are there? The Verilog language allows
|
||||
@@ -270,6 +282,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
|
||||
NetESFunc*fun = new NetESFunc(path_.peek_name(0), sfunc_type,
|
||||
wid, nparms);
|
||||
if (sfunc_info->signed_flag)
|
||||
fun->cast_signed(true);
|
||||
|
||||
/* Now run through the expected parameters. If we find that
|
||||
there are missing parameters, print an error message.
|
||||
@@ -332,7 +346,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
if ((parms_count == 1) && (parms_[0] == 0))
|
||||
parms_count = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
svector<NetExpr*> parms (parms_count);
|
||||
|
||||
@@ -370,20 +384,24 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
dscope, in this case, is the scope of the function, so the
|
||||
return value is the name within that scope. */
|
||||
|
||||
NetNet*res = dscope->find_signal(dscope->basename());
|
||||
if (res == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to locate "
|
||||
"function return value for " << path_ << " in " <<
|
||||
def->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
if (NetNet*res = dscope->find_signal(dscope->basename())) {
|
||||
NetESignal*eres = new NetESignal(res);
|
||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||
return func;
|
||||
}
|
||||
|
||||
assert(res);
|
||||
NetESignal*eres = new NetESignal(res);
|
||||
assert(eres);
|
||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||
return func;
|
||||
if (NetVariable*res = dscope->find_variable(dscope->basename())) {
|
||||
NetEVariable*eres = new NetEVariable(res);
|
||||
eres->set_line(*res);
|
||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||
return func;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": internal error: Unable to locate "
|
||||
"function return value for " << path_
|
||||
<< " in " << def->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -418,6 +436,13 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
|
||||
/* Elaborate all the parameters and attach them to the concat node. */
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
if (parms_[idx] == 0) {
|
||||
cerr << get_line() << ": error: Missing expression "
|
||||
<< (idx+1) << " of concatenation list." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = elab_and_eval(des, scope, parms_[idx]);
|
||||
if (ex == 0) continue;
|
||||
@@ -598,8 +623,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||
NetEConstParam if possible. */
|
||||
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
||||
if (ctmp != 0) {
|
||||
const char*name
|
||||
= lex_strings.add(path_.peek_tail_name());
|
||||
perm_string name
|
||||
= lex_strings.make(path_.peek_tail_name());
|
||||
NetEConstParam*ptmp
|
||||
= new NetEConstParam(found_in, name, ctmp->value());
|
||||
delete tmp;
|
||||
@@ -901,6 +926,16 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
val.has_sign(true);
|
||||
tmp = new NetEConst(val);
|
||||
delete ip;
|
||||
|
||||
} else if (NetECReal*ipc = dynamic_cast<NetECReal*>(ip)) {
|
||||
|
||||
/* When taking the - of a real, fold this into the
|
||||
constant value. */
|
||||
verireal val = - ipc->value();
|
||||
tmp = new NetECReal(val);
|
||||
tmp->set_line( *ip );
|
||||
delete ip;
|
||||
|
||||
} else {
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
@@ -970,6 +1005,38 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.91 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.90 2004/08/28 15:42:11 steve
|
||||
* Add support for $unsigned.
|
||||
*
|
||||
* Revision 1.89 2004/08/26 03:52:07 steve
|
||||
* Add the $is_signed function.
|
||||
*
|
||||
* Revision 1.88 2004/06/17 16:06:18 steve
|
||||
* Help system function signedness survive elaboration.
|
||||
*
|
||||
* Revision 1.87 2004/06/04 23:34:15 steve
|
||||
* Special case for unary - of real literal.
|
||||
*
|
||||
* Revision 1.86 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.85 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.84 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.83 2004/01/21 04:57:40 steve
|
||||
* Generate error when missing concatenation operands.
|
||||
*
|
||||
* Revision 1.82 2003/10/09 16:52:52 steve
|
||||
* Put parameter name in NetEConstParam, not scope.
|
||||
*
|
||||
|
||||
+10
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_lval.cc,v 1.27 2003/09/19 03:30:05 steve Exp $"
|
||||
#ident "$Id: elab_lval.cc,v 1.29 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -40,7 +40,7 @@
|
||||
* 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
|
||||
* NetAssign_ is made wide enough to connect to all the bits of foo,
|
||||
@@ -176,6 +176,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
cerr << get_line() << ": error: " << path_ <<
|
||||
" 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;
|
||||
}
|
||||
@@ -350,6 +352,12 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
|
||||
|
||||
/*
|
||||
* $Log: elab_lval.cc,v $
|
||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.28 2004/08/28 14:59:44 steve
|
||||
* More detailed error message about bad variable.
|
||||
*
|
||||
* Revision 1.27 2003/09/19 03:30:05 steve
|
||||
* Fix name search in elab_lval.
|
||||
*
|
||||
|
||||
+375
-215
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_net.cc,v 1.122 2003/10/30 04:31:34 steve Exp $"
|
||||
#ident "$Id: elab_net.cc,v 1.138 2004/10/04 03:09:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -94,6 +94,7 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
|
||||
return elaborate_net_log_(des, scope, width, rise, fall, decay);
|
||||
case 'l': // <<
|
||||
case 'r': // >>
|
||||
case 'R': // >>>
|
||||
return elaborate_net_shift_(des, scope, width, rise, fall, decay);
|
||||
}
|
||||
|
||||
@@ -138,6 +139,7 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
|
||||
|
||||
case 'l':
|
||||
case 'r':
|
||||
case 'R':
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
@@ -244,15 +246,8 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope,
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
|
||||
switch (op_) {
|
||||
case '+':
|
||||
gate->attribute("LPM_Direction", verinum("ADD"));
|
||||
break;
|
||||
case '-':
|
||||
gate->attribute("LPM_Direction", verinum("SUB"));
|
||||
break;
|
||||
}
|
||||
|
||||
gate->attribute(perm_string::literal("LPM_Direction"),
|
||||
verinum(op_ == '+' ? "ADD" : "SUB"));
|
||||
|
||||
return osig;
|
||||
}
|
||||
@@ -303,95 +298,151 @@ NetNet* PEBinary::elaborate_net_bit_(Design*des, NetScope*scope,
|
||||
lsig->pin_count());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic::TYPE gtype=NetLogic::AND;
|
||||
switch (op_) {
|
||||
case '^': // XOR
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XOR);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X': // XNOR
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XNOR);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
case '&': // AND
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::AND);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'A': // NAND (~&)
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::NAND);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
case '|': // Bitwise OR
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::OR);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'O': // Bitwise NOR
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::NOR);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
case '^': gtype = NetLogic::XOR; break; // XOR
|
||||
case 'X': gtype = NetLogic::XNOR; break; // XNOR
|
||||
case '&': gtype = NetLogic::AND; break; // AND
|
||||
case 'A': gtype = NetLogic::NAND; break; // NAND (~&)
|
||||
case '|': gtype = NetLogic::OR; break; // Bitwise OR
|
||||
case 'O': gtype = NetLogic::NOR; break; // Bitwise NOR
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, gtype);
|
||||
connect(gate->pin(1), lsig->pin(idx));
|
||||
connect(gate->pin(2), rsig->pin(idx));
|
||||
connect(gate->pin(0), osig->pin(idx));
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
des->add_node(gate);
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function attempts to handle the special case of == or !=
|
||||
* compare to a constant value. The caller has determined already that
|
||||
* one of the operands is a NetEConst, and has already elaborated the
|
||||
* other.
|
||||
*/
|
||||
static NetNet* compare_eq_constant(Design*des, NetScope*scope,
|
||||
NetNet*lsig, NetEConst*rexp,
|
||||
char op_code,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay)
|
||||
{
|
||||
if (op_code != 'e' && op_code != 'n')
|
||||
return 0;
|
||||
|
||||
verinum val = rexp->value();
|
||||
|
||||
/* Abandon special case if there are x or z bits in the
|
||||
constant. We can't get the right behavior out of
|
||||
OR/NOR in this case. */
|
||||
if (! val.is_defined())
|
||||
return 0;
|
||||
|
||||
if (val.len() < lsig->pin_count())
|
||||
val = verinum(val, lsig->pin_count());
|
||||
|
||||
/* Look for the very special case that we know the compare
|
||||
results a priori due to different high bits, that are
|
||||
constant pad in the signal. */
|
||||
if (val.len() > lsig->pin_count()) {
|
||||
unsigned idx = lsig->pin_count();
|
||||
verinum::V lpad = verinum::V0;
|
||||
|
||||
while (idx < val.len()) {
|
||||
if (val.get(idx) != lpad) {
|
||||
verinum oval (op_code == 'e'
|
||||
? verinum::V0
|
||||
: verinum::V1,
|
||||
1);
|
||||
NetEConst*ogate = new NetEConst(oval);
|
||||
NetNet*osig = ogate->synthesize(des);
|
||||
delete ogate;
|
||||
return osig;
|
||||
}
|
||||
|
||||
idx +=1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned zeros = 0;
|
||||
unsigned ones = 0;
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
if (val.get(idx) == verinum::V0)
|
||||
zeros += 1;
|
||||
if (val.get(idx) == verinum::V1)
|
||||
ones += 1;
|
||||
}
|
||||
|
||||
/* Now make reduction logic to test that all the 1 bits are 1,
|
||||
and all the 0 bits are 0. The results will be ANDed
|
||||
together later, if needed. NOTE that if the compare is !=,
|
||||
and we know that we will not need an AND later, then fold
|
||||
the final invert into the reduction gate to get the right
|
||||
sense of the output. If we do need the AND later, then we
|
||||
will put the invert on that instead. */
|
||||
NetLogic*zero_gate = 0;
|
||||
NetLogic*ones_gate = 0;
|
||||
if (zeros > 0)
|
||||
zero_gate = new NetLogic(scope,
|
||||
scope->local_symbol(), zeros + 1,
|
||||
(op_code == 'n') ? NetLogic::OR : NetLogic::NOR);
|
||||
if (ones > 0)
|
||||
ones_gate = new NetLogic(scope,
|
||||
scope->local_symbol(), ones + 1,
|
||||
(op_code == 'n') ? NetLogic::NAND : NetLogic::AND);
|
||||
|
||||
unsigned zidx = 0;
|
||||
unsigned oidx = 0;
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
|
||||
if (val.get(idx) == verinum::V0) {
|
||||
zidx += 1;
|
||||
connect(zero_gate->pin(zidx), lsig->pin(idx));
|
||||
}
|
||||
if (val.get(idx) == verinum::V1) {
|
||||
oidx += 1;
|
||||
connect(ones_gate->pin(oidx), lsig->pin(idx));
|
||||
}
|
||||
}
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
if (zero_gate && ones_gate) {
|
||||
NetNet*and_sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 2);
|
||||
and_sig->local_flag(true);
|
||||
connect(and_sig->pin(0), zero_gate->pin(0));
|
||||
connect(and_sig->pin(1), ones_gate->pin(0));
|
||||
NetLogic*and_gate = new NetLogic(scope,
|
||||
scope->local_symbol(), 3,
|
||||
(op_code == 'n') ? NetLogic::OR : NetLogic::AND);
|
||||
connect(and_gate->pin(0), osig->pin(0));
|
||||
connect(and_gate->pin(1), and_sig->pin(0));
|
||||
connect(and_gate->pin(2), and_sig->pin(1));
|
||||
|
||||
des->add_node(and_gate);
|
||||
des->add_node(zero_gate);
|
||||
des->add_node(ones_gate);
|
||||
|
||||
} else if (zero_gate) {
|
||||
connect(zero_gate->pin(0), osig->pin(0));
|
||||
des->add_node(zero_gate);
|
||||
} else {
|
||||
assert(ones_gate);
|
||||
connect(ones_gate->pin(0), osig->pin(0));
|
||||
des->add_node(ones_gate);
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
@@ -408,21 +459,90 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const
|
||||
{
|
||||
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0),
|
||||
*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
if (lsig == 0) {
|
||||
/* Elaborate the operands of the compare first as expressions
|
||||
(so that the eval_tree method can reduce constant
|
||||
expressions, including parameters) then turn those results
|
||||
into synthesized nets. */
|
||||
NetExpr*lexp = left_->elaborate_expr(des, scope);
|
||||
if (lexp == 0) {
|
||||
cerr << get_line() << ": error: Cannot elaborate ";
|
||||
left_->dump(cerr);
|
||||
cerr << endl;
|
||||
return 0;
|
||||
}
|
||||
if (rsig == 0) {
|
||||
|
||||
if (NetExpr*tmp = lexp->eval_tree()) {
|
||||
delete lexp;
|
||||
lexp = tmp;
|
||||
}
|
||||
|
||||
NetExpr*rexp = right_->elaborate_expr(des, scope);
|
||||
if (rexp == 0) {
|
||||
cerr << get_line() << ": error: Cannot elaborate ";
|
||||
right_->dump(cerr);
|
||||
cerr << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NetExpr*tmp = rexp->eval_tree()) {
|
||||
delete rexp;
|
||||
rexp = tmp;
|
||||
}
|
||||
|
||||
NetNet*lsig = 0;
|
||||
NetNet*rsig = 0;
|
||||
|
||||
/* Handle the special case that the right or left
|
||||
sub-expression is a constant value. The compare_eq_constant
|
||||
function will return an elaborated result if it can make
|
||||
use of the situation, or 0 if it cannot. */
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(rexp)) {
|
||||
|
||||
lsig = lexp->synthesize(des);
|
||||
if (lsig == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
"Cannot elaborate net for " << *lexp << endl;
|
||||
}
|
||||
assert(lsig);
|
||||
delete lexp;
|
||||
lexp = 0;
|
||||
|
||||
NetNet*osig = compare_eq_constant(des, scope,
|
||||
lsig, tmp, op_,
|
||||
rise, fall, decay);
|
||||
if (osig != 0) {
|
||||
delete rexp;
|
||||
return osig;
|
||||
}
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(lexp)) {
|
||||
|
||||
rsig = rexp->synthesize(des);
|
||||
assert(rsig);
|
||||
delete rexp;
|
||||
|
||||
NetNet*osig = compare_eq_constant(des, scope,
|
||||
rsig, tmp, op_,
|
||||
rise, fall, decay);
|
||||
if (osig != 0) {
|
||||
delete lexp;
|
||||
return osig;
|
||||
}
|
||||
}
|
||||
|
||||
if (lsig == 0) {
|
||||
lsig = lexp->synthesize(des);
|
||||
assert(lsig);
|
||||
delete lexp;
|
||||
}
|
||||
|
||||
if (rsig == 0) {
|
||||
rsig = rexp->synthesize(des);
|
||||
assert(rsig);
|
||||
delete rexp;
|
||||
}
|
||||
|
||||
unsigned dwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count();
|
||||
|
||||
@@ -657,6 +777,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
div->set_signed(lsig->get_signed() && rsig->get_signed());
|
||||
|
||||
// Connect the left and right inputs of the divider to the
|
||||
// nets that are the left and right expressions.
|
||||
@@ -675,6 +796,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, lwidth);
|
||||
osig->local_flag(true);
|
||||
osig->set_signed(div->get_signed());
|
||||
|
||||
for (unsigned idx = 0 ; idx < rwidth ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
@@ -757,8 +879,8 @@ NetNet* PEBinary::elaborate_net_log_(Design*des, NetScope*scope,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const
|
||||
{
|
||||
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0),
|
||||
*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
if (lsig == 0) {
|
||||
cerr << get_line() << ": error: Cannot elaborate ";
|
||||
left_->dump(cerr);
|
||||
@@ -934,6 +1056,9 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
if (lsig->pin_count() > lwidth)
|
||||
lwidth = lsig->pin_count();
|
||||
|
||||
bool right_flag = op_ == 'r' || op_ == 'R';
|
||||
bool signed_flag = op_ == 'R';
|
||||
|
||||
/* Handle the special case of a constant shift amount. There
|
||||
is no reason in this case to create a gate at all, just
|
||||
connect the lsig to the osig with the bit positions
|
||||
@@ -956,6 +1081,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
des->add_node(zero);
|
||||
|
||||
if (op_ == 'l') {
|
||||
/* Left shift means put some zeros on the bottom
|
||||
of the vector. */
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < dist ; idx += 1)
|
||||
connect(osig->pin(idx), zero->pin(0));
|
||||
@@ -965,7 +1092,17 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
for ( ; idx < lwidth ; idx += 1)
|
||||
connect(osig->pin(idx), zero->pin(0));
|
||||
|
||||
} else if (op_ == 'R') {
|
||||
/* Signed right shift. */
|
||||
unsigned idx;
|
||||
unsigned keep = lsig->pin_count()-dist;
|
||||
for (idx = 0 ; idx < keep ; idx += 1)
|
||||
connect(osig->pin(idx), lsig->pin(idx+dist));
|
||||
for (idx = keep ; idx < lwidth ; idx += 1)
|
||||
connect(osig->pin(idx), lsig->pin(keep+dist-1));
|
||||
|
||||
} else {
|
||||
/* Unsigned right shift. */
|
||||
assert(op_ == 'r');
|
||||
unsigned idx;
|
||||
unsigned keep = lsig->pin_count()-dist;
|
||||
@@ -990,7 +1127,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
// Make the shift device itself, and the output
|
||||
// NetNet. Connect the Result output pins to the osig signal
|
||||
NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(),
|
||||
lwidth, rsig->pin_count());
|
||||
lwidth, rsig->pin_count(),
|
||||
right_flag, signed_flag);
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, lwidth);
|
||||
@@ -1021,17 +1159,6 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(rsig->pin(idx), gate->pin_Distance(idx));
|
||||
|
||||
if (op_ == 'r') {
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
tmp->local_flag(true);
|
||||
NetConst*dir = new NetConst(scope, scope->local_symbol(),
|
||||
verinum::V1);
|
||||
connect(dir->pin(0), gate->pin_Direction());
|
||||
connect(tmp->pin(0), gate->pin_Direction());
|
||||
des->add_node(dir);
|
||||
}
|
||||
|
||||
des->add_node(gate);
|
||||
|
||||
return osig;
|
||||
@@ -1039,7 +1166,10 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
|
||||
/*
|
||||
* This method elaborates a call to a function in the context of a
|
||||
* continuous assignment.
|
||||
* continuous assignment. The definition of the function contains a
|
||||
* list of the ports, and an output port. The NetEUFunc that I create
|
||||
* here has a port for all the input ports and the output port. The
|
||||
* ports are connected by pins.
|
||||
*/
|
||||
NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
@@ -1070,6 +1200,21 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
sub->set_signed(true);
|
||||
return sub;
|
||||
}
|
||||
/* handle $unsigned like $signed */
|
||||
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $unsigned() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
|
||||
fall, decay, drive0, drive1);
|
||||
sub->set_signed(false);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Look up the function definition. */
|
||||
NetFuncDef*def = des->find_function(scope, path_);
|
||||
@@ -1084,6 +1229,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
NetScope*dscope = def->scope();
|
||||
assert(dscope);
|
||||
|
||||
/* This must be a ufuction that returns a signal. */
|
||||
assert(def->return_sig());
|
||||
|
||||
/* check the validity of the parameters. */
|
||||
if (! check_call_matches_definition_(des, dscope))
|
||||
return 0;
|
||||
@@ -1092,9 +1240,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
and collect the resulting NetNet objects. All the
|
||||
parameters take on the size of the target port. */
|
||||
|
||||
svector<NetNet*> eparms (def->port_count()-1);
|
||||
svector<NetNet*> eparms (def->port_count());
|
||||
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
|
||||
const NetNet* port_reg = def->port(idx+1);
|
||||
const NetNet* port_reg = def->port(idx);
|
||||
NetNet*tmp = parms_[idx]->elaborate_net(des, scope,
|
||||
port_reg->pin_count(),
|
||||
0, 0, 0,
|
||||
@@ -1117,7 +1265,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
|
||||
|
||||
NetUserFunc*net = new NetUserFunc(scope,
|
||||
scope->local_symbol().c_str(),
|
||||
scope->local_symbol(),
|
||||
dscope);
|
||||
des->add_node(net);
|
||||
|
||||
@@ -1125,7 +1273,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
of the function net. */
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE,
|
||||
def->port(0)->pin_count());
|
||||
def->return_sig()->pin_count());
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
@@ -1133,7 +1281,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||
|
||||
/* Connect the parameter pins to the parameter expressions. */
|
||||
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
|
||||
const NetNet* port = def->port(idx+1);
|
||||
const NetNet* port = def->port(idx);
|
||||
NetNet*cur = eparms[idx];
|
||||
|
||||
NetNet*tmp = pad_to_width(des, cur, port->pin_count());
|
||||
@@ -1349,7 +1497,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||
assert(pc);
|
||||
verinum pvalue = pc->value();
|
||||
|
||||
sig = new NetNet(scope, path_.peek_name(0),
|
||||
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
|
||||
NetNet::IMPLICIT, pc->expr_width());
|
||||
NetConst*cp = new NetConst(scope, scope->local_symbol(),
|
||||
pvalue);
|
||||
@@ -1365,13 +1513,34 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for the error case that the name is not found, and it
|
||||
is hierarchical. We can't just create a name in another
|
||||
scope, it's just not allowed. */
|
||||
if (sig == 0 && path_.component_count() != 1) {
|
||||
cerr << get_line() << ": error: The hierarchical name "
|
||||
<< path_ << " is undefined in "
|
||||
<< scope->name() << "." << endl;
|
||||
|
||||
hname_t tmp_path = path_;
|
||||
delete[] tmp_path.remove_tail_name();
|
||||
|
||||
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
|
||||
if (tmp_scope == 0) {
|
||||
cerr << get_line() << ": : I can't even find "
|
||||
<< "the scope " << tmp_path << "." << endl;
|
||||
}
|
||||
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fallback, this may be an implicitly declared net. */
|
||||
if (sig == 0) {
|
||||
NetNet::Type nettype = scope->default_nettype();
|
||||
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
|
||||
nettype, 1);
|
||||
|
||||
sig = new NetNet(scope, path_.peek_name(0),
|
||||
NetNet::IMPLICIT, 1);
|
||||
|
||||
if (error_implicit) {
|
||||
if (error_implicit || (nettype == NetNet::NONE)) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< scope->name() << "." << path_.peek_name(0)
|
||||
<< " not defined in this scope." << endl;
|
||||
@@ -1627,10 +1796,11 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
if (sig == 0) {
|
||||
NetNet::Type nettype = scope->default_nettype();
|
||||
|
||||
if (implicit_net_ok && !error_implicit) {
|
||||
if (implicit_net_ok && !error_implicit && nettype!=NetNet::NONE) {
|
||||
|
||||
sig = new NetNet(scope, path_.peek_name(0),
|
||||
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
|
||||
NetNet::IMPLICIT, 1);
|
||||
|
||||
if (warn_implicit) {
|
||||
@@ -1671,7 +1841,7 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
|
||||
if (msb_ && lsb_) {
|
||||
/* Detect a part select. Evaluate the bits and elaborate
|
||||
the l-value by creating a sub-net that links to just
|
||||
the right pins. */
|
||||
the right pins. */
|
||||
verinum*mval = msb_->eval_const(des, scope);
|
||||
assert(mval);
|
||||
verinum*lval = lsb_->eval_const(des, scope);
|
||||
@@ -1781,7 +1951,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
||||
if (msb_ && lsb_) {
|
||||
/* Detect a part select. Evaluate the bits and elaborate
|
||||
the l-value by creating a sub-net that links to just
|
||||
the right pins. */
|
||||
the right pins. */
|
||||
verinum*mval = msb_->eval_const(des, scope);
|
||||
assert(mval);
|
||||
verinum*lval = lsb_->eval_const(des, scope);
|
||||
@@ -1859,6 +2029,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, lwidth);
|
||||
net->local_flag(true);
|
||||
net->set_signed(value_->has_sign());
|
||||
|
||||
/* when expanding a constant to fit into the net, extend
|
||||
the Vx or Vz values if they are in the sign position,
|
||||
@@ -1899,6 +2070,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, value_->len());
|
||||
net->local_flag(true);
|
||||
net->set_signed(value_->has_sign());
|
||||
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
|
||||
*value_);
|
||||
for (unsigned idx = 0 ; idx < value_->len() ; idx += 1)
|
||||
@@ -2167,7 +2339,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
break;
|
||||
}
|
||||
|
||||
NetNet* sig;
|
||||
NetNet* sig = 0;
|
||||
NetLogic*gate;
|
||||
|
||||
// Handle the special case of a 2's complement of a constant
|
||||
@@ -2206,6 +2378,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
}
|
||||
assert(sub_sig);
|
||||
|
||||
bool reduction=false;
|
||||
NetLogic::TYPE gtype = NetLogic::AND;
|
||||
|
||||
switch (op_) {
|
||||
case '~': // Bitwise NOT
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE,
|
||||
@@ -2225,95 +2400,17 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
|
||||
case 'N': // Reduction NOR
|
||||
case '!': // Reduction NOT
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::NOR);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
|
||||
reduction=true; gtype = NetLogic::NOR; break;
|
||||
case '&': // Reduction AND
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::AND);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
|
||||
reduction=true; gtype = NetLogic::AND; break;
|
||||
case '|': // Reduction OR
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::OR);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
|
||||
reduction=true; gtype = NetLogic::OR; break;
|
||||
case '^': // Reduction XOR
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::XOR);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
|
||||
reduction=true; gtype = NetLogic::XOR; break;
|
||||
case 'A': // Reduction NAND (~&)
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::NAND);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
|
||||
|
||||
reduction=true; gtype = NetLogic::NAND; break;
|
||||
case 'X': // Reduction XNOR (~^)
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), NetLogic::XNOR);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
break;
|
||||
reduction=true; gtype = NetLogic::XNOR; break;
|
||||
|
||||
case '-': // Unary 2's complement.
|
||||
sig = new NetNet(scope, scope->local_symbol(),
|
||||
@@ -2363,7 +2460,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
default:
|
||||
NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(),
|
||||
sig->pin_count());
|
||||
sub->attribute("LPM_Direction", verinum("SUB"));
|
||||
sub->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
|
||||
|
||||
des->add_node(sub);
|
||||
|
||||
@@ -2396,13 +2493,76 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
cerr << "internal error: Unhandled UNARY '" << op_ << "'" << endl;
|
||||
sig = 0;
|
||||
}
|
||||
if (reduction) {
|
||||
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
|
||||
sig->local_flag(true);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
1+sub_sig->pin_count(), gtype);
|
||||
connect(gate->pin(0), sig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), sub_sig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
gate->rise_time(rise);
|
||||
gate->fall_time(fall);
|
||||
gate->decay_time(decay);
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_net.cc,v $
|
||||
* Revision 1.138 2004/10/04 03:09:38 steve
|
||||
* Fix excessive error message.
|
||||
*
|
||||
* Revision 1.137 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.136 2004/10/04 00:25:46 steve
|
||||
* Error message to match assertion.
|
||||
*
|
||||
* Revision 1.135 2004/09/24 04:25:19 steve
|
||||
* Detect and prevent implicit declaration of hierarchical names.
|
||||
*
|
||||
* Revision 1.134 2004/08/28 15:42:12 steve
|
||||
* Add support for $unsigned.
|
||||
*
|
||||
* Revision 1.133 2004/06/30 02:16:26 steve
|
||||
* Implement signed divide and signed right shift in nets.
|
||||
*
|
||||
* Revision 1.132 2004/06/24 15:22:23 steve
|
||||
* Code cleanup from Larry.
|
||||
*
|
||||
* Revision 1.131 2004/06/22 18:41:48 steve
|
||||
* Fix broken calcuation of NE for constant.
|
||||
*
|
||||
* Revision 1.130 2004/06/18 16:38:22 steve
|
||||
* compare-to-constant uses sig len, not val len.
|
||||
*
|
||||
* Revision 1.129 2004/06/16 23:32:58 steve
|
||||
* Handle equality compare to constants specially.
|
||||
*
|
||||
* Revision 1.128 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.127 2004/06/01 01:04:57 steve
|
||||
* Fix synthesis method for logical and/or
|
||||
*
|
||||
* Revision 1.126 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.125 2004/02/20 18:53:34 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.124 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.123 2004/02/15 04:23:48 steve
|
||||
* Fix evaluation of compare to constant expression.
|
||||
*
|
||||
* Revision 1.122 2003/10/30 04:31:34 steve
|
||||
* Catch real variables in net expressions.
|
||||
*
|
||||
|
||||
+10
-5
@@ -17,12 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_pexpr.cc,v 1.20 2003/05/30 02:55:32 steve Exp $"
|
||||
#ident "$Id: elab_pexpr.cc,v 1.21 2004/02/20 06:22:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "compiler.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <iostream>
|
||||
@@ -136,19 +137,20 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(name);
|
||||
perm_string perm_name = lex_strings.make(name);
|
||||
delete name;
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(perm_name);
|
||||
if (ex == 0) {
|
||||
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, hname_t(name));
|
||||
NetExpr*res = new NetEParam(des, pscope, perm_name);
|
||||
res->set_line(*this);
|
||||
assert(res);
|
||||
delete name;
|
||||
|
||||
assert(idx_ == 0);
|
||||
if (msb_ && lsb_) {
|
||||
@@ -229,6 +231,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* 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
|
||||
|
||||
+183
-73
@@ -17,12 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.27 2003/09/13 01:01:51 steve Exp $"
|
||||
#ident "$Id: elab_scope.cc,v 1.35 2004/09/10 00:15:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* Elaboration happens in two passes, generally. The first scans the
|
||||
@@ -46,6 +47,11 @@
|
||||
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Elaborate scope "
|
||||
<< scope->name() << "." << 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
|
||||
@@ -57,7 +63,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// the pform and just place a NetEParam placeholder in the
|
||||
// place of the elaborated expression.
|
||||
|
||||
typedef map<string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
|
||||
|
||||
@@ -129,7 +135,25 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val, 0, 0, false);
|
||||
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);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -171,12 +195,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// elaborate_scope method of the PTask for detailed
|
||||
// processing.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator tasks_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
|
||||
|
||||
for (tasks_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope::TASK);
|
||||
(*cur).second->elaborate_scope(des, task_scope);
|
||||
}
|
||||
@@ -186,12 +210,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// perspective of scopes. So handle them exactly the same
|
||||
// way.
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator funcs_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
|
||||
|
||||
for (funcs_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope::FUNC);
|
||||
(*cur).second->elaborate_scope(des, func_scope);
|
||||
}
|
||||
@@ -201,7 +225,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// 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 ++ ) {
|
||||
|
||||
@@ -226,7 +249,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// elaboration, so do it now. This allows for normal
|
||||
// elaboration to reference these events.
|
||||
|
||||
for (map<string,PEvent*>::const_iterator et = events.begin()
|
||||
for (map<perm_string,PEvent*>::const_iterator et = events.begin()
|
||||
; et != events.end() ; et ++ ) {
|
||||
|
||||
(*et).second->elaborate_scope(des, scope);
|
||||
@@ -287,79 +310,142 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
return;
|
||||
}
|
||||
|
||||
// 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());
|
||||
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
|
||||
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 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);
|
||||
assert( (msb == 0) || (lsb != 0) );
|
||||
|
||||
// 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);
|
||||
long instance_low = 0;
|
||||
long instance_high = 0;
|
||||
long instance_count = 1;
|
||||
bool instance_array = false;
|
||||
|
||||
// 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.
|
||||
if (msb) {
|
||||
instance_array = true;
|
||||
instance_high = msb->as_long();
|
||||
instance_low = lsb->as_long();
|
||||
if (instance_high > instance_low)
|
||||
instance_count = instance_high - instance_low + 1;
|
||||
else
|
||||
instance_count = instance_low - instance_high + 1;
|
||||
}
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
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) {
|
||||
|
||||
perm_string use_name = get_name();
|
||||
|
||||
if (instance_array) {
|
||||
char name_buf[128];
|
||||
int instance_idx = idx;
|
||||
if (instance_low < instance_high)
|
||||
instance_idx = instance_low + idx;
|
||||
else
|
||||
instance_idx = instance_low - idx;
|
||||
|
||||
snprintf(name_buf, sizeof name_buf,
|
||||
"%s[%d]", get_name().str(), instance_idx);
|
||||
use_name = lex_strings.make(name_buf);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Module instance " << use_name
|
||||
<< " becomes child of " << sc->name()
|
||||
<< "." << 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
// 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;
|
||||
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];
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< sc->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< sc->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -385,7 +471,7 @@ void PData::elaborate_scope(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
const char*basename = hname_.peek_tail_name();
|
||||
NetVariable*tmp = new NetVariable(lex_strings.add(basename));
|
||||
NetVariable*tmp = new NetVariable(lex_strings.make(basename));
|
||||
tmp->set_line(*this);
|
||||
sub_scope->add_variable(tmp);
|
||||
}
|
||||
@@ -439,8 +525,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*my_scope = scope;
|
||||
|
||||
if (name_ != "") {
|
||||
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
|
||||
if (name_ != 0) {
|
||||
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
|
||||
? NetScope::FORK_JOIN
|
||||
: NetScope::BEGIN_END);
|
||||
}
|
||||
@@ -549,6 +635,30 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+137
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.32 2003/09/20 05:24:00 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.36 2004/09/27 22:34:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,6 +29,7 @@
|
||||
# include "PGate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
@@ -174,7 +175,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
||||
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
@@ -195,7 +196,7 @@ 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<string,PTask*>::const_iterator mtask_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
|
||||
|
||||
for (mtask_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++) {
|
||||
@@ -210,31 +211,42 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||
Module*rmod) const
|
||||
{
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
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 " << my_scope->name()
|
||||
<< " is in parent " << my_scope->parent()->name()
|
||||
<< " instead of " << scope->name()
|
||||
<< endl;
|
||||
}
|
||||
assert(my_scope->parent() == scope);
|
||||
|
||||
if (! rmod->elaborate_sig(des, my_scope))
|
||||
flag = false;
|
||||
|
||||
if (msb_) {
|
||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
||||
"are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* A function definition exists within an elaborated module.
|
||||
* 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.
|
||||
*/
|
||||
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
string fname = scope->basename();
|
||||
perm_string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
/* Make sure the function has at least one input port. If it
|
||||
@@ -248,21 +260,81 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
NetNet*ret_sig = 0;
|
||||
NetVariable*ret_real = 0;
|
||||
|
||||
/* 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;
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
switch (return_type_.type) {
|
||||
|
||||
case PTF_REG:
|
||||
if (return_type_.range) {
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[0]);
|
||||
assert(me);
|
||||
NetExpr*le = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[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->port_type(NetNet::POUTPUT);
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_real = new NetVariable(fname);
|
||||
ret_real->set_line(*this);
|
||||
scope->add_variable(ret_real);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: I don't know how "
|
||||
<< "to deal with return type of function "
|
||||
<< scope->basename() << "." << endl;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
|
||||
@@ -271,8 +343,8 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
as two components: <func>.<port>. */
|
||||
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
string pname = path.peek_name(1);
|
||||
string ppath = path.peek_name(0);
|
||||
perm_string pname = lex_strings.make(path.peek_name(1));
|
||||
perm_string ppath = lex_strings.make(path.peek_name(0));
|
||||
|
||||
if (ppath != scope->basename()) {
|
||||
cerr << get_line() << ": internal error: function "
|
||||
@@ -288,14 +360,19 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
<< scope->name() << " is missing port "
|
||||
<< pname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
cerr << get_line() << ": Continuing..." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ports[idx+1] = tmp;
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
|
||||
NetFuncDef*def = new NetFuncDef(scope, ports);
|
||||
NetFuncDef*def = 0;
|
||||
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
|
||||
if (ret_real) def = new NetFuncDef(scope, ret_real, ports);
|
||||
|
||||
assert(def);
|
||||
scope->set_func_def(def);
|
||||
}
|
||||
|
||||
@@ -366,6 +443,7 @@ bool PGate::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. */
|
||||
@@ -373,7 +451,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
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);
|
||||
|
||||
if (scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Bad scope component for name "
|
||||
<< hname_ << endl;
|
||||
assert(scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +598,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
delete lexp;
|
||||
delete rexp;
|
||||
|
||||
string name = hname_.peek_tail_name();
|
||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
||||
|
||||
long lnum = lval.as_long();
|
||||
long rnum = rval.as_long();
|
||||
@@ -525,7 +609,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
} else {
|
||||
|
||||
string name = hname_.peek_tail_name();
|
||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
||||
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
@@ -539,6 +623,20 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+373
-169
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elaborate.cc,v 1.293 2003/10/26 04:49:51 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.308 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -176,8 +176,8 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||
} else {
|
||||
verinum tmpv (0UL, lval->pin_count()-cnt);
|
||||
NetConst*tmp = new NetConst(scope,
|
||||
scope->local_symbol(),
|
||||
tmpv);
|
||||
scope->local_symbol(),
|
||||
tmpv);
|
||||
des->add_node(tmp);
|
||||
for (idx = cnt
|
||||
; idx < lval->pin_count()
|
||||
@@ -191,8 +191,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||
strength and delays. */
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < cnt ; idx += 1) {
|
||||
NetBUFZ*dev = new NetBUFZ(scope,
|
||||
scope->local_symbol());
|
||||
NetBUFZ*dev = new NetBUFZ(scope,scope->local_symbol());
|
||||
connect(lval->pin(idx), dev->pin(0));
|
||||
connect(rid->pin(idx), dev->pin(1));
|
||||
dev->rise_time(rise_time);
|
||||
@@ -212,9 +211,9 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||
|
||||
} else {
|
||||
NetConst*dev = new NetConst(scope,
|
||||
scope->local_symbol(),
|
||||
verinum::V0);
|
||||
|
||||
scope->local_symbol(),
|
||||
verinum::V0);
|
||||
|
||||
des->add_node(dev);
|
||||
dev->pin(0).drive0(drive0);
|
||||
dev->pin(0).drive1(drive1);
|
||||
@@ -269,7 +268,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned count = 1;
|
||||
long low = 0, high = 0;
|
||||
string name = get_name();
|
||||
string name = string(get_name());
|
||||
|
||||
if (name == "")
|
||||
name = scope->local_symbol();
|
||||
@@ -351,7 +350,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||
index = low - idx;
|
||||
|
||||
tmp << name << "<" << index << ">";
|
||||
const string inm = tmp.str();
|
||||
perm_string inm = lex_strings.make(tmp.str());
|
||||
|
||||
switch (type()) {
|
||||
case AND:
|
||||
@@ -493,24 +492,15 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||
*/
|
||||
void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
assert(scope);
|
||||
|
||||
// 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);
|
||||
|
||||
const svector<PExpr*>*pins;
|
||||
// This is the array of pin expressions, shuffled to match the
|
||||
// order of the declaration. If the source instantiation uses
|
||||
// bind by order, this is the same as the source
|
||||
// list. Otherwise, the source list is rearranged by name
|
||||
// binding into this list.
|
||||
svector<PExpr*>pins (rmod->port_count());
|
||||
|
||||
// Detect binding by name. If I am binding by name, then make
|
||||
// up a pins array that reflects the positions of the named
|
||||
@@ -518,7 +508,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
// place, then get the binding from the base class.
|
||||
if (pins_) {
|
||||
unsigned nexp = rmod->port_count();
|
||||
svector<PExpr*>*exp = new svector<PExpr*>(nexp);
|
||||
|
||||
// Scan the bindings, matching them with port names.
|
||||
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
|
||||
@@ -541,7 +530,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
// If I already bound something to this port, then
|
||||
// the (*exp) array will already have a pointer
|
||||
// value where I want to place this expression.
|
||||
if ((*exp)[pidx]) {
|
||||
if (pins[pidx]) {
|
||||
cerr << get_line() << ": error: port ``" <<
|
||||
pins_[idx].name << "'' already bound." <<
|
||||
endl;
|
||||
@@ -551,10 +540,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
|
||||
// OK, do the binding by placing the expression in
|
||||
// the right place.
|
||||
(*exp)[pidx] = pins_[idx].parm;
|
||||
pins[pidx] = pins_[idx].parm;
|
||||
}
|
||||
|
||||
pins = exp;
|
||||
|
||||
} else if (pin_count() == 0) {
|
||||
|
||||
@@ -563,11 +551,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
connect-by-name list, so we'll allow it and assume
|
||||
that is the case. */
|
||||
|
||||
svector<PExpr*>*tmp = new svector<PExpr*>(rmod->port_count());
|
||||
for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1)
|
||||
(*tmp)[idx] = 0;
|
||||
|
||||
pins = tmp;
|
||||
pins[idx] = 0;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -590,11 +575,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
pins = get_pins();
|
||||
}
|
||||
|
||||
// Elaborate this instance of the module. The recursive
|
||||
|
||||
// Elaborate these instances of the module. The recursive
|
||||
// elaboration causes the module to generate a netlist with
|
||||
// the ports represented by NetNet objects. I will find them
|
||||
// later.
|
||||
rmod->elaborate(des, my_scope);
|
||||
|
||||
NetScope::scope_vec_t&instance = scope->instance_arrays[get_name()];
|
||||
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
||||
rmod->elaborate(des, instance[inst]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now connect the ports of the newly elaborated designs to
|
||||
// the expressions that are the instantiation parameters. Scan
|
||||
@@ -606,12 +598,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
// to a concatenation, or connected to an internally
|
||||
// unconnected port.
|
||||
|
||||
for (unsigned idx = 0 ; idx < pins->count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) {
|
||||
|
||||
// Skip unconnected module ports. This happens when a
|
||||
// null parameter is passed in.
|
||||
|
||||
if ((*pins)[idx] == 0) {
|
||||
if (pins[idx] == 0) {
|
||||
|
||||
// While we're here, look to see if this
|
||||
// unconnected (from the outside) port is an
|
||||
@@ -622,7 +614,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
if (mport.count() == 0)
|
||||
continue;
|
||||
|
||||
NetNet*tmp = des->find_signal(my_scope,
|
||||
NetNet*tmp = des->find_signal(instance[0],
|
||||
mport[0]->path());
|
||||
assert(tmp);
|
||||
|
||||
@@ -640,47 +632,59 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Inside the module, the port is zero or more signals
|
||||
// that were already elaborated. List all those signals
|
||||
// and the NetNet equivalents.
|
||||
// and the NetNet equivalents, for all the instances.
|
||||
svector<PEIdent*> mport = rmod->get_port(idx);
|
||||
svector<NetNet*>prts (mport.count());
|
||||
svector<NetNet*>prts (mport.count() * instance.count());
|
||||
|
||||
// Count the internal pins of the port.
|
||||
unsigned prts_pin_count = 0;
|
||||
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
||||
PEIdent*pport = mport[ldx];
|
||||
assert(pport);
|
||||
prts[ldx] = pport->elaborate_port(des, my_scope);
|
||||
if (prts[ldx] == 0)
|
||||
continue;
|
||||
|
||||
assert(prts[ldx]);
|
||||
prts_pin_count += prts[ldx]->pin_count();
|
||||
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
||||
NetScope*inst_scope = instance[inst];
|
||||
|
||||
// Scan the module sub-ports for this instance...
|
||||
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
||||
unsigned lbase = inst * mport.count();
|
||||
PEIdent*pport = mport[ldx];
|
||||
assert(pport);
|
||||
prts[lbase + ldx]
|
||||
= pport->elaborate_port(des, inst_scope);
|
||||
if (prts[lbase + ldx] == 0)
|
||||
continue;
|
||||
|
||||
assert(prts[lbase + ldx]);
|
||||
prts_pin_count += prts[lbase + ldx]->pin_count();
|
||||
}
|
||||
}
|
||||
|
||||
// If I find that the port in unconnected inside the
|
||||
// module, then there is nothing to connect. Skip the
|
||||
// parameter.
|
||||
// argument.
|
||||
if (prts_pin_count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Elaborate the expression that connects to the module
|
||||
// port. sig is the thing outside the module that
|
||||
// connects to the port.
|
||||
// We know by design that each instance has the same
|
||||
// width port. Therefore, the prts_pin_count must be an
|
||||
// even multiple of the instance count.
|
||||
assert(prts_pin_count % instance.count() == 0);
|
||||
|
||||
// Elaborate the expression that connects to the
|
||||
// module[s] port. sig is the thing outside the module
|
||||
// that connects to the port.
|
||||
|
||||
NetNet*sig;
|
||||
if ((prts.count() >= 1)
|
||||
&& (prts[0]->port_type() != NetNet::PINPUT)) {
|
||||
|
||||
sig = (*pins)[idx]->elaborate_lnet(des, scope, true);
|
||||
sig = pins[idx]->elaborate_lnet(des, scope, true);
|
||||
if (sig == 0) {
|
||||
cerr << (*pins)[idx]->get_line() << ": error: "
|
||||
cerr << pins[idx]->get_line() << ": error: "
|
||||
<< "Output port expression must support "
|
||||
<< "continuous assignment." << endl;
|
||||
cerr << (*pins)[idx]->get_line() << ": : "
|
||||
cerr << pins[idx]->get_line() << ": : "
|
||||
<< "Port of " << rmod->mod_name()
|
||||
<< " is " << rmod->ports[idx]->name << endl;
|
||||
des->errors += 1;
|
||||
@@ -688,11 +692,20 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
}
|
||||
|
||||
} else {
|
||||
sig = (*pins)[idx]->elaborate_net(des, scope,
|
||||
prts_pin_count,
|
||||
0, 0, 0);
|
||||
/* Input to module. elaborate the expression to
|
||||
the desired width. If this in an instance
|
||||
array, then let the net determine it's own
|
||||
width. We use that, then, to decide how to hook
|
||||
it up. */
|
||||
unsigned desired_pin_count = prts_pin_count;
|
||||
if (instance.count() != 1)
|
||||
desired_pin_count = 0;
|
||||
|
||||
sig = pins[idx]->elaborate_net(des, scope,
|
||||
desired_pin_count,
|
||||
0, 0, 0);
|
||||
if (sig == 0) {
|
||||
cerr << (*pins)[idx]->get_line()
|
||||
cerr << pins[idx]->get_line()
|
||||
<< ": internal error: Port expression "
|
||||
<< "too complicated for elaboration." << endl;
|
||||
continue;
|
||||
@@ -708,10 +721,25 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we are working with an instance array, then the
|
||||
signal width must match the port width exactly. */
|
||||
if ((instance.count() != 1)
|
||||
&& (sig->pin_count() != prts_pin_count)
|
||||
&& (sig->pin_count() != prts_pin_count/instance.count())) {
|
||||
cerr << pins[idx]->get_line() << ": error: "
|
||||
<< "Port expression width " << sig->pin_count()
|
||||
<< " does not match expected width " << prts_pin_count
|
||||
<< " or " << (prts_pin_count/instance.count())
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the parts have matching pin counts. If
|
||||
// not, they are different widths. Note that idx is 0
|
||||
// based, but users count parameter positions from 1.
|
||||
if (prts_pin_count != sig->pin_count()) {
|
||||
if ((instance.count() == 1)
|
||||
&& (prts_pin_count != sig->pin_count())) {
|
||||
cerr << get_line() << ": warning: Port " << (idx+1)
|
||||
<< " (" << rmod->ports[idx]->name << ") of "
|
||||
<< type_ << " expects " << prts_pin_count <<
|
||||
@@ -742,9 +770,17 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
// Connect this many of the port pins. If the expression
|
||||
// is too small, the reduce the number of connects.
|
||||
unsigned ccount = prts_pin_count;
|
||||
if (sig->pin_count() < ccount)
|
||||
if (instance.count() == 1 && sig->pin_count() < ccount)
|
||||
ccount = sig->pin_count();
|
||||
|
||||
// The spin_modulus is the width of the signal (not the
|
||||
// port) if this is an instance array. This causes
|
||||
// signals wide enough for a single instance to be
|
||||
// connected to all the instances.
|
||||
unsigned spin_modulus = prts_pin_count;
|
||||
if (instance.count() != 1)
|
||||
spin_modulus = sig->pin_count();
|
||||
|
||||
// Now scan the concatenation that makes up the port,
|
||||
// connecting pins until we run out of port pins or sig
|
||||
// pins.
|
||||
@@ -755,7 +791,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
if (cnt > ccount)
|
||||
cnt = ccount;
|
||||
for (unsigned p = 0 ; p < cnt ; p += 1) {
|
||||
connect(sig->pin(spin), prts[ldx-1]->pin(p));
|
||||
connect(sig->pin(spin%spin_modulus),
|
||||
prts[ldx-1]->pin(p));
|
||||
ccount -= 1;
|
||||
spin += 1;
|
||||
}
|
||||
@@ -767,6 +804,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -778,8 +816,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||
void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
{
|
||||
|
||||
string my_name = get_name();
|
||||
if (my_name == "")
|
||||
perm_string my_name = get_name();
|
||||
if (my_name == 0)
|
||||
my_name = scope->local_symbol();
|
||||
|
||||
/* When the parser notices delay expressions in front of a
|
||||
@@ -793,6 +831,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
assert(udp);
|
||||
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
|
||||
net->rise_time(rise_time);
|
||||
net->fall_time(fall_time);
|
||||
@@ -808,17 +847,110 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
|
||||
delete[]attrib_list;
|
||||
|
||||
|
||||
// This is the array of pin expressions, shuffled to match the
|
||||
// order of the declaration. If the source instantiation uses
|
||||
// bind by order, this is the same as the source
|
||||
// list. Otherwise, the source list is rearranged by name
|
||||
// binding into this list.
|
||||
svector<PExpr*>pins;
|
||||
|
||||
// Detect binding by name. If I am binding by name, then make
|
||||
// up a pins array that reflects the positions of the named
|
||||
// ports. If this is simply positional binding in the first
|
||||
// place, then get the binding from the base class.
|
||||
if (pins_) {
|
||||
unsigned nexp = udp->ports.count();
|
||||
pins = svector<PExpr*>(nexp);
|
||||
|
||||
// Scan the bindings, matching them with port names.
|
||||
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
|
||||
|
||||
// Given a binding, look at the module port names
|
||||
// for the position that matches the binding name.
|
||||
unsigned pidx = udp->find_port(pins_[idx].name);
|
||||
|
||||
// If the port name doesn't exist, the find_port
|
||||
// method will return the port count. Detect that
|
||||
// as an error.
|
||||
if (pidx == nexp) {
|
||||
cerr << get_line() << ": error: port ``" <<
|
||||
pins_[idx].name << "'' is not a port of "
|
||||
<< get_name() << "." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If I already bound something to this port, then
|
||||
// the (*exp) array will already have a pointer
|
||||
// value where I want to place this expression.
|
||||
if (pins[pidx]) {
|
||||
cerr << get_line() << ": error: port ``" <<
|
||||
pins_[idx].name << "'' already bound." <<
|
||||
endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// OK, do the binding by placing the expression in
|
||||
// the right place.
|
||||
pins[pidx] = pins_[idx].parm;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Otherwise, this is a positional list of port
|
||||
connections. In this case, the port count must be
|
||||
right. Check that is is, the get the pin list. */
|
||||
|
||||
if (pin_count() != udp->ports.count()) {
|
||||
cerr << get_line() << ": error: Wrong number "
|
||||
"of ports. Expecting " << udp->ports.count() <<
|
||||
", got " << pin_count() << "."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// No named bindings, just use the positional list I
|
||||
// already have.
|
||||
assert(pin_count() == udp->ports.count());
|
||||
pins = get_pins();
|
||||
}
|
||||
|
||||
|
||||
/* Handle the output port of the primitive special. It is an
|
||||
output port (the only output port) so must be passed an
|
||||
l-value net. */
|
||||
if (pins[0] == 0) {
|
||||
cerr << get_line() << ": warning: output port unconnected."
|
||||
<< endl;
|
||||
|
||||
} else {
|
||||
NetNet*sig = pins[0]->elaborate_lnet(des, scope, true);
|
||||
if (sig == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Output port expression is not valid." << endl;
|
||||
cerr << get_line() << ": : Output "
|
||||
<< "port of " << udp->name_
|
||||
<< " is " << udp->ports[0] << "." << endl;
|
||||
des->errors += 1;
|
||||
} else {
|
||||
connect(sig->pin(0), net->pin(0));
|
||||
}
|
||||
}
|
||||
|
||||
/* Run through the pins, making netlists for the pin
|
||||
expressions and connecting them to the pin in question. All
|
||||
of this is independent of the nature of the UDP. */
|
||||
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||
if (pin(idx) == 0)
|
||||
for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) {
|
||||
if (pins[idx] == 0)
|
||||
continue;
|
||||
|
||||
NetNet*sig = pin(idx)->elaborate_net(des, scope, 1, 0, 0, 0);
|
||||
NetNet*sig = pins[idx]->elaborate_net(des, scope, 1, 0, 0, 0);
|
||||
if (sig == 0) {
|
||||
cerr << "internal error: Expression too complicated "
|
||||
"for elaboration:" << *pin(idx) << endl;
|
||||
"for elaboration:" << pins[idx] << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -828,7 +960,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
|
||||
// All done. Add the object to the design.
|
||||
des->add_node(net);
|
||||
}
|
||||
@@ -837,7 +969,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Look for the module type
|
||||
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end())
|
||||
return elaborate_sig_mod_(des, scope, (*mod).second);
|
||||
|
||||
@@ -848,15 +980,16 @@ bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
|
||||
void PGModule::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Look for the module type
|
||||
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end()) {
|
||||
elaborate_mod_(des, (*mod).second, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try a primitive type
|
||||
map<string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
|
||||
map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
|
||||
if (udp != pform_primitives.end()) {
|
||||
assert((*udp).second);
|
||||
elaborate_udp_(des, (*udp).second, scope);
|
||||
return;
|
||||
}
|
||||
@@ -868,14 +1001,14 @@ void PGModule::elaborate(Design*des, NetScope*scope) const
|
||||
void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
||||
{
|
||||
// Look for the module type
|
||||
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end()) {
|
||||
elaborate_scope_mod_(des, (*mod).second, sc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try a primitive type
|
||||
map<string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
|
||||
map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
|
||||
if (udp != pform_primitives.end())
|
||||
return;
|
||||
|
||||
@@ -929,12 +1062,7 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
|
||||
*/
|
||||
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
|
||||
{
|
||||
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope);
|
||||
if (NetExpr*tmp = dex->eval_tree()) {
|
||||
delete dex;
|
||||
dex = tmp;
|
||||
}
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
@@ -1011,17 +1139,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
|
||||
assert(rval());
|
||||
NetExpr*rv = rval()->elaborate_expr(des, scope);
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
NetExpr*rv = elab_and_eval(des, scope, rval());
|
||||
if (rv == 0) return 0;
|
||||
assert(rv);
|
||||
|
||||
/* Try to evaluate the expression, at least as far as possible. */
|
||||
if (NetExpr*tmp = rv->eval_tree()) {
|
||||
delete rv;
|
||||
rv = tmp;
|
||||
}
|
||||
|
||||
/* Rewrite delayed assignments as assignments that are
|
||||
delayed. For example, a = #<d> b; becomes:
|
||||
@@ -1088,6 +1209,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||
|
||||
} else {
|
||||
NetPDelay*de = new NetPDelay(delay, a2);
|
||||
de->set_line(*this);
|
||||
st = de;
|
||||
}
|
||||
|
||||
@@ -1122,6 +1244,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate non-blocking assignments. The statement is of the general
|
||||
* form:
|
||||
*
|
||||
* <lval> <= #<delay> <rval> ;
|
||||
*/
|
||||
NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
@@ -1138,10 +1264,16 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
|
||||
if (rv == 0)
|
||||
return 0;
|
||||
|
||||
/* Handle the (common) case that the r-value is a vector. This
|
||||
includes just about everything but reals. In this case, we
|
||||
need to pad the r-value to match the width of the l-value.
|
||||
|
||||
{ unsigned wid = count_lval_width(lv);
|
||||
rv->set_width(wid);
|
||||
rv = pad_to_width(rv, wid);
|
||||
If in this case the l-val is a variable (i.e. real) then
|
||||
the width to pad to will be 0, so this code is harmless. */
|
||||
if (rv->expr_type() == NetExpr::ET_VECTOR) {
|
||||
unsigned wid = count_lval_width(lv);
|
||||
rv->set_width(wid);
|
||||
rv = pad_to_width(rv, wid);
|
||||
}
|
||||
|
||||
NetExpr*delay = 0;
|
||||
@@ -1171,7 +1303,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
||||
: NetBlock::SEQU;
|
||||
|
||||
NetScope*nscope = 0;
|
||||
if (name_.length()) {
|
||||
if (name_.str() != 0) {
|
||||
nscope = scope->child(name_);
|
||||
if (nscope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
@@ -1195,7 +1327,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
||||
// statement. There is no need to keep the block node. Also,
|
||||
// don't elide named blocks, because they might be referenced
|
||||
// elsewhere.
|
||||
if ((list_.count() == 1) && (name_.length() == 0)) {
|
||||
if ((list_.count() == 1) && (name_.str() == 0)) {
|
||||
assert(list_[0]);
|
||||
NetProc*tmp = list_[0]->elaborate(des, nscope);
|
||||
return tmp;
|
||||
@@ -1234,22 +1366,13 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": error: Unable to elaborate this case"
|
||||
" expression." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to evaluate the case expression. */
|
||||
if (! dynamic_cast<NetEConst*>(expr)) {
|
||||
NetExpr*tmp = expr->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete expr;
|
||||
expr = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count the items in the case statement. Note that there may
|
||||
be some cases that have multiple guards. Count each as a
|
||||
separate item. */
|
||||
@@ -1295,17 +1418,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||
NetExpr*gu = 0;
|
||||
NetProc*st = 0;
|
||||
assert(cur->expr[e]);
|
||||
gu = cur->expr[e]->elaborate_expr(des, scope);
|
||||
|
||||
/* Try to evaluate the guard expression down to a
|
||||
simple constant. */
|
||||
if (! dynamic_cast<NetEConst*>(gu)) {
|
||||
NetExpr*tmp = gu->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete gu;
|
||||
gu = tmp;
|
||||
}
|
||||
}
|
||||
gu = elab_and_eval(des, scope, cur->expr[e]);
|
||||
|
||||
if (cur->stat)
|
||||
st = cur->stat->elaborate(des, scope);
|
||||
@@ -1323,18 +1436,13 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
||||
assert(scope);
|
||||
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": error: Unable to elaborate"
|
||||
" condition expression." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
NetExpr*tmp = expr->eval_tree();
|
||||
if (tmp) {
|
||||
delete expr;
|
||||
expr = tmp;
|
||||
}
|
||||
|
||||
// If the condition of the conditional statement is constant,
|
||||
// then look at the value and elaborate either the if statement
|
||||
@@ -1541,7 +1649,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||
if (port->port_type() == NetNet::POUTPUT)
|
||||
continue;
|
||||
|
||||
NetExpr*rv = parms_[idx]->elaborate_expr(des, scope);
|
||||
NetExpr*rv = elab_and_eval(des, scope, parms_[idx]);
|
||||
NetAssign_*lv = new NetAssign_(port);
|
||||
NetAssign*pr = new NetAssign(lv, rv);
|
||||
block->append(pr);
|
||||
@@ -1802,7 +1910,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||
list. The NetEvProbe objects all refer back to the NetEvent
|
||||
object. */
|
||||
|
||||
NetEvent*ev = new NetEvent(lex_strings.add(scope->local_symbol().c_str()));
|
||||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
ev->set_line(*this);
|
||||
unsigned expr_count = 0;
|
||||
|
||||
@@ -1954,6 +2062,8 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
||||
|
||||
const PExpr *pe = expr_[0]->expr();
|
||||
|
||||
/* Elaborate wait expression. Don't eval yet, we will do that
|
||||
shortly, after we apply a reduction or. */
|
||||
NetExpr*expr = pe->elaborate_expr(des, scope);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": error: Unable to elaborate"
|
||||
@@ -1962,6 +2072,67 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If the condition expression is more then 1 bits, then
|
||||
// generate a reduction operator to get the result down to
|
||||
// one bit. In other words, Turn <e> into |<e>;
|
||||
|
||||
if (expr->expr_width() < 1) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
"incomprehensible wait expression width (0)." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (expr->expr_width() > 1) {
|
||||
assert(expr->expr_width() > 1);
|
||||
NetEUReduce*cmp = new NetEUReduce('|', expr);
|
||||
expr = cmp;
|
||||
}
|
||||
|
||||
/* precalculate as much as possible of the wait expression. */
|
||||
if (NetExpr*tmp = expr->eval_tree()) {
|
||||
delete expr;
|
||||
expr = tmp;
|
||||
}
|
||||
|
||||
/* Detect the unusual case that the wait expression is
|
||||
constant. Constant true is OK (it becomes transparent) but
|
||||
constant false is almost certainly not what is intended. */
|
||||
assert(expr->expr_width() == 1);
|
||||
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
||||
verinum val = ce->value();
|
||||
assert(val.len() == 1);
|
||||
|
||||
/* Constant true -- wait(1) <s1> reduces to <s1>. */
|
||||
if (val[0] == verinum::V1) {
|
||||
delete expr;
|
||||
assert(enet);
|
||||
return enet;
|
||||
}
|
||||
|
||||
/* Otherwise, false. wait(0) blocks permanently. */
|
||||
|
||||
cerr << get_line() << ": warning: wait expression is "
|
||||
<< "constant false." << endl;
|
||||
cerr << get_line() << ": : The statement will "
|
||||
<< "block permanently." << endl;
|
||||
|
||||
/* Create an event wait and an otherwise unreferenced
|
||||
event variable to force a perpetual wait. */
|
||||
NetEvent*wait_event = new NetEvent(scope->local_symbol());
|
||||
scope->add_event(wait_event);
|
||||
|
||||
NetEvWait*wait = new NetEvWait(0);
|
||||
wait->add_event(wait_event);
|
||||
wait->set_line(*this);
|
||||
|
||||
delete expr;
|
||||
delete enet;
|
||||
return wait;
|
||||
}
|
||||
|
||||
/* Invert the sense of the test with an exclusive NOR. In
|
||||
other words, if this adjusted expression returns TRUE, then
|
||||
wait. */
|
||||
assert(expr->expr_width() == 1);
|
||||
expr = new NetEBComp('N', expr, new NetEConst(verinum(verinum::V1)));
|
||||
NetExpr*tmp = expr->eval_tree();
|
||||
@@ -1970,25 +2141,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
||||
expr = tmp;
|
||||
}
|
||||
|
||||
/* Detect the unusual case that the wait expression is
|
||||
constant. Constant true is OK (it becomes transparent) but
|
||||
constant false is almost certainly not what is intended. */
|
||||
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
||||
verinum val = ce->value();
|
||||
assert(val.len() == 1);
|
||||
if (val[0] == verinum::V1) {
|
||||
delete expr;
|
||||
assert(enet);
|
||||
return enet;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": warning: wait expression is "
|
||||
<< "constant false." << endl;
|
||||
cerr << get_line() << ": : The statement will "
|
||||
<< "block permanently." << endl;
|
||||
}
|
||||
|
||||
NetEvent*wait_event = new NetEvent(lex_strings.add(scope->local_symbol().c_str()));
|
||||
NetEvent*wait_event = new NetEvent(scope->local_symbol());
|
||||
scope->add_event(wait_event);
|
||||
|
||||
NetEvWait*wait = new NetEvWait(0 /* noop */);
|
||||
@@ -2027,7 +2180,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
||||
if (enet == 0)
|
||||
return loop;
|
||||
|
||||
/* Create a sequential block to conbine the wait loop and the
|
||||
/* Create a sequential block to combine the wait loop and the
|
||||
delayed statement. */
|
||||
NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
|
||||
block->append(loop);
|
||||
@@ -2045,6 +2198,10 @@ NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const
|
||||
enet = statement_->elaborate(des, scope);
|
||||
if (enet == 0)
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
enet = new NetBlock(NetBlock::SEQU, 0);
|
||||
enet->set_line(*this);
|
||||
}
|
||||
|
||||
if ((expr_.count() == 1) && (expr_[0]->type() == PEEvent::POSITIVE))
|
||||
@@ -2173,18 +2330,15 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||
/* Elaborate the condition expression. Try to evaluate it too,
|
||||
in case it is a constant. This is an interesting case
|
||||
worthy of a warning. */
|
||||
NetExpr*ce = cond_->elaborate_expr(des, scope);
|
||||
NetExpr*ce = elab_and_eval(des, scope, cond_);
|
||||
if (ce == 0) {
|
||||
delete top;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NetExpr*tmp = ce->eval_tree()) {
|
||||
if (dynamic_cast<NetEConst*>(tmp)) {
|
||||
cerr << get_line() << ": warning: condition expression "
|
||||
"of for-loop is constant." << endl;
|
||||
}
|
||||
ce = tmp;
|
||||
if (dynamic_cast<NetEConst*>(ce)) {
|
||||
cerr << get_line() << ": warning: condition expression "
|
||||
"of for-loop is constant." << endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -2220,6 +2374,13 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||
void PFunction::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetFuncDef*def = scope->func_def();
|
||||
if (def == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "No function definition for function "
|
||||
<< scope->name() << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(def);
|
||||
|
||||
NetProc*st = statement_->elaborate(des, scope);
|
||||
@@ -2250,18 +2411,13 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
NetExpr*expr = expr_->elaborate_expr(des, scope);
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": Unable to elaborate"
|
||||
" repeat expression." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
NetExpr*tmp = expr->eval_tree();
|
||||
if (tmp) {
|
||||
delete expr;
|
||||
expr = tmp;
|
||||
}
|
||||
|
||||
NetProc*stat = statement_->elaborate(des, scope);
|
||||
if (stat == 0) return 0;
|
||||
@@ -2324,7 +2480,6 @@ void PTask::elaborate(Design*des, NetScope*task) const
|
||||
|
||||
NetProc*st;
|
||||
if (statement_ == 0) {
|
||||
cerr << get_line() << ": warning: task has no statement." << endl;
|
||||
st = new NetBlock(NetBlock::SEQU, 0);
|
||||
|
||||
} else {
|
||||
@@ -2378,7 +2533,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, scope),
|
||||
NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_),
|
||||
statement_->elaborate(des, scope));
|
||||
return loop;
|
||||
}
|
||||
@@ -2393,7 +2548,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
|
||||
|
||||
// Elaborate functions.
|
||||
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
|
||||
@@ -2405,7 +2560,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
// Elaborate the task definitions. This is done before the
|
||||
// behaviors so that task calls may reference these, and after
|
||||
// the signals so that the tasks can reference them.
|
||||
typedef map<string,PTask*>::const_iterator mtask_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
|
||||
for (mtask_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++) {
|
||||
|
||||
@@ -2502,7 +2657,8 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
if (! anyedge_test)
|
||||
break;
|
||||
|
||||
top->attribute("_ivl_schedule_push", verinum(1));
|
||||
top->attribute(perm_string::literal("_ivl_schedule_push"),
|
||||
verinum(1));
|
||||
} while (0);
|
||||
|
||||
}
|
||||
@@ -2515,7 +2671,7 @@ struct root_elem {
|
||||
NetScope *scope;
|
||||
};
|
||||
|
||||
Design* elaborate(list<const char*>roots)
|
||||
Design* elaborate(list<perm_string>roots)
|
||||
{
|
||||
svector<root_elem*> root_elems(roots.size());
|
||||
bool rc = true;
|
||||
@@ -2525,15 +2681,15 @@ Design* elaborate(list<const char*>roots)
|
||||
// module and elaborate what I find.
|
||||
Design*des = new Design;
|
||||
|
||||
for (list<const char*>::const_iterator root = roots.begin()
|
||||
for (list<perm_string>::const_iterator root = roots.begin()
|
||||
; root != roots.end()
|
||||
; root++) {
|
||||
|
||||
// Look for the root module in the list.
|
||||
map<string,Module*>::const_iterator mod = pform_modules.find(*root);
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(*root);
|
||||
if (mod == pform_modules.end()) {
|
||||
cerr << "error: Unable to find the root module \""
|
||||
<< (*root) << "\" in the Verilog source." << endl;
|
||||
<< (*root) << "\" in the Verilog source." << endl;
|
||||
cerr << " : Perhaps ``-s " << (*root)
|
||||
<< "'' is incorrect?" << endl;
|
||||
des->errors++;
|
||||
@@ -2541,12 +2697,13 @@ Design* elaborate(list<const char*>roots)
|
||||
}
|
||||
|
||||
Module *rmod = (*mod).second;
|
||||
|
||||
|
||||
// Make the root scope, then scan the pform looking for scopes
|
||||
// and parameters.
|
||||
// and parameters.
|
||||
NetScope*scope = des->make_root_scope(*root);
|
||||
scope->time_unit(rmod->time_unit);
|
||||
scope->time_precision(rmod->time_precision);
|
||||
scope->default_nettype(rmod->default_nettype);
|
||||
des->set_precision(rmod->time_precision);
|
||||
if (! rmod->elaborate_scope(des, scope)) {
|
||||
delete des;
|
||||
@@ -2612,6 +2769,53 @@ Design* elaborate(list<const char*>roots)
|
||||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.308 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.307 2004/09/05 21:07:26 steve
|
||||
* Support degenerat wait statements.
|
||||
*
|
||||
* Revision 1.306 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.305 2004/06/30 15:32:02 steve
|
||||
* Propagate source line number in synthetic delay statements.
|
||||
*
|
||||
* Revision 1.304 2004/06/20 15:59:06 steve
|
||||
* Only pad the width of vector r-values.
|
||||
*
|
||||
* Revision 1.303 2004/06/13 04:56:54 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.302 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.301 2004/05/25 03:42:58 steve
|
||||
* Handle wait with constant-false expression.
|
||||
*
|
||||
* Revision 1.300 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.299 2004/03/08 00:10:29 steve
|
||||
* Verilog2001 new style port declartions for primitives.
|
||||
*
|
||||
* Revision 1.298 2004/03/07 20:04:10 steve
|
||||
* MOre thorough use of elab_and_eval function.
|
||||
*
|
||||
* Revision 1.297 2004/02/20 18:53:34 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.296 2004/02/18 17:11:55 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.295 2004/01/21 04:35:03 steve
|
||||
* Get rid of useless warning.
|
||||
*
|
||||
* Revision 1.294 2004/01/13 03:42:49 steve
|
||||
* Handle wide expressions in wait condition.
|
||||
*
|
||||
* Revision 1.293 2003/10/26 04:49:51 steve
|
||||
* Attach line number information to for loop parts.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: emit.cc,v 1.75 2003/09/13 01:30:07 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.77 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -335,17 +335,18 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
}
|
||||
}
|
||||
|
||||
void NetScope::emit_defs(struct target_t*tgt) const
|
||||
bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
switch (type_) {
|
||||
case MODULE:
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_defs(tgt);
|
||||
flag &= cur->emit_defs(tgt);
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
tgt->func_def(this);
|
||||
flag &= tgt->func_def(this);
|
||||
break;
|
||||
case TASK:
|
||||
tgt->task_def(this);
|
||||
@@ -354,6 +355,7 @@ void NetScope::emit_defs(struct target_t*tgt) const
|
||||
break;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
@@ -370,7 +372,7 @@ bool Design::emit(struct target_t*tgt) const
|
||||
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);
|
||||
|
||||
@@ -386,9 +388,9 @@ bool Design::emit(struct target_t*tgt) const
|
||||
|
||||
|
||||
// emit task and function definitions
|
||||
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_defs(tgt);
|
||||
rc &= (*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
// emit the processes
|
||||
@@ -509,6 +511,14 @@ bool emit(const Design*des, const char*type)
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.77 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* 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.75 2003/09/13 01:30:07 steve
|
||||
* Missing case warnings.
|
||||
*
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_attrib.cc,v 1.6 2003/01/27 05:09:17 steve Exp $"
|
||||
#ident "$Id: eval_attrib.cc,v 1.7 2004/02/20 18:53:35 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -33,7 +33,7 @@
|
||||
* for passing to netlist devices.
|
||||
*/
|
||||
|
||||
attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
|
||||
unsigned&natt,
|
||||
const Design*des,
|
||||
const NetScope*scope)
|
||||
@@ -46,7 +46,7 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
|
||||
unsigned idx = 0;
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator iter_t;
|
||||
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;
|
||||
@@ -74,6 +74,9 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
|
||||
/*
|
||||
* $Log: eval_attrib.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+69
-24
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_tree.cc,v 1.59 2003/10/31 02:47:11 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.62 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -1124,8 +1124,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
return 0;
|
||||
|
||||
assert(scope_);
|
||||
assert(name_.peek_name(1) == 0);
|
||||
const NetExpr*expr = scope_->get_parameter(name_.peek_name(0));
|
||||
const NetExpr*expr = scope_->get_parameter(name_);
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to match "
|
||||
<< "parameter " << name_ << " in scope "
|
||||
@@ -1142,8 +1141,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
// return the constant value.
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(nexpr)) {
|
||||
verinum val = tmp->value();
|
||||
const char*name = lex_strings.add(name_.peek_name(0));
|
||||
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
|
||||
NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
|
||||
ptmp->set_line(*this);
|
||||
delete nexpr;
|
||||
return ptmp;
|
||||
@@ -1151,8 +1149,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
|
||||
if (NetECReal*tmp = dynamic_cast<NetECReal*>(nexpr)) {
|
||||
verireal val = tmp->value();
|
||||
const char*name = lex_strings.add(name_.peek_name(0));
|
||||
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
|
||||
NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
|
||||
ptmp->set_line(*this);
|
||||
delete nexpr;
|
||||
return ptmp;
|
||||
@@ -1171,7 +1168,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
|
||||
// The result can be saved as the value of the parameter for
|
||||
// future reference, and return a copy to the caller.
|
||||
scope_->replace_parameter(name_.peek_name(0), res);
|
||||
scope_->replace_parameter(name_, res);
|
||||
|
||||
/* Return as a result a NetEConstParam or NetECRealParam
|
||||
object, depending on the type of the expression. */
|
||||
@@ -1190,8 +1187,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
assert(tmp);
|
||||
|
||||
verinum val = tmp->value();
|
||||
const char*name = lex_strings.add(name_.peek_name(0));
|
||||
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
|
||||
NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
|
||||
|
||||
return ptmp;
|
||||
}
|
||||
@@ -1208,8 +1204,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
assert(tmp);
|
||||
|
||||
verireal val = tmp->value();
|
||||
const char*name = lex_strings.add(name_.peek_name(0));
|
||||
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
|
||||
NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
|
||||
|
||||
return ptmp;
|
||||
}
|
||||
@@ -1256,7 +1251,7 @@ NetEConst* NetESelect::eval_tree()
|
||||
for (unsigned long idx = 0 ; idx < expr_width() ; idx += 1) {
|
||||
if ((bval >= 0) && ((unsigned long) bval < eval.len()))
|
||||
oval.set(idx, eval.get(bval));
|
||||
else
|
||||
else
|
||||
oval.set(idx, verinum::Vx);
|
||||
|
||||
bval += 1;
|
||||
@@ -1310,18 +1305,50 @@ NetExpr* NetETernary::eval_tree()
|
||||
if (c == 0)
|
||||
return 0;
|
||||
|
||||
/* Check the boolean value of the constant condition
|
||||
expression. Note that the X case is handled explicitly, so
|
||||
we must differentiate. */
|
||||
|
||||
verinum cond_value = c->value();
|
||||
bool true_flag = false;
|
||||
bool x_flag = false;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cond_value.len() ; idx += 1) {
|
||||
switch (cond_value.get(idx)) {
|
||||
case verinum::V1:
|
||||
true_flag = true;
|
||||
break;
|
||||
case verinum::V0:
|
||||
break;
|
||||
default:
|
||||
x_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If the condition is 1 or 0, return the true or false
|
||||
expression. Try to evaluate the expression down as far as
|
||||
we can. */
|
||||
|
||||
if (c->value().get(0) == verinum::V1)
|
||||
if (true_flag) {
|
||||
if (debug_eval_tree) {
|
||||
cerr << get_line() << ": debug: Evaluate ternary with "
|
||||
<< "constant condition value: " << c->value() << endl;
|
||||
cerr << get_line() << ": : Selecting true case: "
|
||||
<< *true_val_ << endl;
|
||||
}
|
||||
return true_val_->dup_expr();
|
||||
}
|
||||
|
||||
|
||||
if (c->value().get(0) == verinum::V0)
|
||||
if (! x_flag) {
|
||||
if (debug_eval_tree) {
|
||||
cerr << get_line() << ": debug: Evaluate ternary with "
|
||||
<< "constant condition value: " << c->value() << endl;
|
||||
cerr << get_line() << ": : Selecting false case: "
|
||||
<< *true_val_ << endl;
|
||||
}
|
||||
return false_val_->dup_expr();
|
||||
|
||||
}
|
||||
|
||||
/* Here we have a more complex case. We need to evaluate both
|
||||
expressions down to constants then compare the values to
|
||||
@@ -1337,13 +1364,15 @@ NetExpr* NetETernary::eval_tree()
|
||||
return 0;
|
||||
|
||||
|
||||
unsigned size = t->expr_width();
|
||||
assert(size == f->expr_width());
|
||||
unsigned tsize = t->expr_width();
|
||||
unsigned fsize = f->expr_width();
|
||||
/* Size of the result is the size of the widest operand. */
|
||||
unsigned rsize = tsize > fsize? tsize : fsize;
|
||||
|
||||
verinum val (verinum::V0, size);
|
||||
for (unsigned idx = 0 ; idx < size ; idx += 1) {
|
||||
verinum::V tv = t->value().get(idx);
|
||||
verinum::V fv = f->value().get(idx);
|
||||
verinum val (verinum::V0, rsize);
|
||||
for (unsigned idx = 0 ; idx < rsize ; idx += 1) {
|
||||
verinum::V tv = idx < tsize? t->value().get(idx) : verinum::V0;
|
||||
verinum::V fv = idx < rsize? f->value().get(idx) : verinum::V0;
|
||||
|
||||
if (tv == fv)
|
||||
val.set(idx, tv);
|
||||
@@ -1351,6 +1380,13 @@ NetExpr* NetETernary::eval_tree()
|
||||
val.set(idx, verinum::Vx);
|
||||
}
|
||||
|
||||
if (debug_eval_tree) {
|
||||
cerr << get_line() << ": debug: Evaluate ternary with "
|
||||
<< "constant condition value: " << c->value() << endl;
|
||||
cerr << get_line() << ": : Blending cases to get "
|
||||
<< val << endl;
|
||||
}
|
||||
|
||||
NetEConst*rc = new NetEConst(val);
|
||||
rc->set_line(*this);
|
||||
return rc;
|
||||
@@ -1387,7 +1423,7 @@ NetEConst* NetEUnary::eval_tree()
|
||||
|
||||
case '-': {
|
||||
if (val.is_defined()) {
|
||||
|
||||
|
||||
verinum tmp (verinum::V0, val.len());
|
||||
tmp.has_sign(val.has_sign());
|
||||
val = tmp - val;
|
||||
@@ -1515,6 +1551,15 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.62 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.61 2004/09/10 23:51:42 steve
|
||||
* Fix the evaluation of constant ternary expressions.
|
||||
*
|
||||
* Revision 1.60 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.59 2003/10/31 02:47:11 steve
|
||||
* NetEUReduce has its own dup_expr method.
|
||||
*
|
||||
|
||||
+8
-8
@@ -218,11 +218,11 @@ output [1:48] k;
|
||||
wire [1:56] YY;
|
||||
|
||||
assign YY[1:28]=c; assign YY[29:56]=d;
|
||||
|
||||
|
||||
assign k[1]=YY[14]; assign k[2]=YY[17]; assign k[3]=YY[11]; assign k[4]=YY[24]; assign k[5]=YY[1]; assign k[6]=YY[5];
|
||||
assign k[7]=YY[3]; assign k[8]=YY[28]; assign k[9]=YY[15]; assign k[10]=YY[6]; assign k[11]=YY[21]; assign k[12]=YY[10];
|
||||
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
|
||||
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
|
||||
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
|
||||
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
|
||||
assign k[25]=YY[41]; assign k[26]=YY[52]; assign k[27]=YY[31]; assign k[28]=YY[37]; assign k[29]=YY[47]; assign k[30]=YY[55];
|
||||
assign k[31]=YY[30]; assign k[32]=YY[40]; assign k[33]=YY[51]; assign k[34]=YY[45]; assign k[35]=YY[33]; assign k[36]=YY[48];
|
||||
assign k[37]=YY[44]; assign k[38]=YY[49]; assign k[39]=YY[39]; assign k[40]=YY[56]; assign k[41]=YY[34]; assign k[42]=YY[53];
|
||||
@@ -252,13 +252,13 @@ input [1:64] key;
|
||||
output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
|
||||
wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
|
||||
wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
|
||||
|
||||
|
||||
pc1 pc1(key, c0x, d0x);
|
||||
|
||||
rol1 rc1(c1x, c0x); rol1 rd1(d1x, d0x);
|
||||
rol1 rc2(c2x, c1x); rol1 rd2(d2x, d1x);
|
||||
rol2 rc3(c3x, c2x); rol2 rd3(d3x, d2x);
|
||||
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
|
||||
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
|
||||
rol2 rc5(c5x, c4x); rol2 rd5(d5x, d4x);
|
||||
rol2 rc6(c6x, c5x); rol2 rd6(d6x, d5x);
|
||||
rol2 rc7(c7x, c6x); rol2 rd7(d7x, d6x);
|
||||
@@ -272,7 +272,7 @@ rol2 rce(c14x, c13x); rol2 rde(d14x, d13x);
|
||||
rol2 rcf(c15x, c14x); rol2 rdf(d15x, d14x);
|
||||
rol1 rcg(c16x, c15x); rol1 rdg(d16x, d15x);
|
||||
|
||||
|
||||
|
||||
pc2 pc2x1(c1x,d1x,k1x);
|
||||
pc2 pc2x2(c2x,d2x,k2x);
|
||||
pc2 pc2x3(c3x,d3x,k3x);
|
||||
@@ -913,7 +913,7 @@ assign l0x[17]=pt[62]; assign l0x[18]=pt[54]; assign l0x[19]=pt[46
|
||||
assign l0x[21]=pt[30]; assign l0x[22]=pt[22]; assign l0x[23]=pt[14]; assign l0x[24]=pt[6];
|
||||
assign l0x[25]=pt[64]; assign l0x[26]=pt[56]; assign l0x[27]=pt[48]; assign l0x[28]=pt[40];
|
||||
assign l0x[29]=pt[32]; assign l0x[30]=pt[24]; assign l0x[31]=pt[16]; assign l0x[32]=pt[8];
|
||||
|
||||
|
||||
assign r0x[1]=pt[57]; assign r0x[2]=pt[49]; assign r0x[3]=pt[41]; assign r0x[4]=pt[33];
|
||||
assign r0x[5]=pt[25]; assign r0x[6]=pt[17]; assign r0x[7]=pt[9]; assign r0x[8]=pt[1];
|
||||
assign r0x[9]=pt[59]; assign r0x[10]=pt[51]; assign r0x[11]=pt[43]; assign r0x[12]=pt[35];
|
||||
@@ -935,7 +935,7 @@ assign e[9]=ri[6]; assign e[10]=ri[7]; assign e[11]=ri[8]; assign e[12]=r
|
||||
assign e[17]=ri[12]; assign e[18]=ri[13]; assign e[19]=ri[12]; assign e[20]=ri[13]; assign e[21]=ri[14]; assign e[22]=ri[15]; assign e[23]=ri[16]; assign e[24]=ri[17];
|
||||
assign e[25]=ri[16]; assign e[26]=ri[17]; assign e[27]=ri[18]; assign e[28]=ri[19]; assign e[29]=ri[20]; assign e[30]=ri[21]; assign e[31]=ri[20]; assign e[32]=ri[21];
|
||||
assign e[33]=ri[22]; assign e[34]=ri[23]; assign e[35]=ri[24]; assign e[36]=ri[25]; assign e[37]=ri[24]; assign e[38]=ri[25]; assign e[39]=ri[26]; assign e[40]=ri[27];
|
||||
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
|
||||
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
+5
-5
@@ -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
|
||||
*
|
||||
*
|
||||
* 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 ;
|
||||
|
||||
@@ -26,21 +26,21 @@
|
||||
* 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
|
||||
|
||||
initial
|
||||
begin
|
||||
$my_hello;
|
||||
$finish ;
|
||||
|
||||
+11
-11
@@ -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
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
||||
+5
-5
@@ -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.3 2000/11/04 01:53:24 steve Exp $"
|
||||
* $Id: sqrt.vl,v 1.4 2004/10/04 01:10:56 steve Exp $"
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ module main;
|
||||
// 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.
|
||||
|
||||
|
||||
assign a[0] = a0;
|
||||
assign a[1] = a1;
|
||||
assign a[2] = a2;
|
||||
|
||||
+2
-2
@@ -28,7 +28,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;
|
||||
|
||||
@@ -39,7 +39,7 @@ module main;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
|
||||
+108
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: expr_synth.cc,v 1.52 2003/11/10 19:39:20 steve Exp $"
|
||||
#ident "$Id: expr_synth.cc,v 1.59 2004/06/30 02:16:26 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -54,11 +54,11 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
assert(lsig->pin_count() == rsig->pin_count());
|
||||
unsigned width=lsig->pin_count();
|
||||
|
||||
string path = lsig->scope()->local_symbol();
|
||||
perm_string path = lsig->scope()->local_symbol();
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = osig->scope()->local_symbol();
|
||||
perm_string oname = osig->scope()->local_symbol();
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(lsig->pin(idx), adder->pin_DataA(idx));
|
||||
@@ -69,10 +69,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
|
||||
switch (op()) {
|
||||
case '+':
|
||||
adder->attribute("LPM_Direction", verinum("ADD"));
|
||||
adder->attribute(perm_string::literal("LPM_Direction"), verinum("ADD"));
|
||||
break;
|
||||
case '-':
|
||||
adder->attribute("LPM_Direction", verinum("SUB"));
|
||||
adder->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
|
||||
string oname = scope->local_hsymbol();
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
/* If the rsig bit is constant, then look for special
|
||||
@@ -190,12 +190,12 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
switch (op_) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
break;
|
||||
|
||||
@@ -204,11 +204,11 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
is very much like sig != 0. (0 > sig) shouldn't
|
||||
happen. */
|
||||
if (rcon) {
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
@@ -216,11 +216,11 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
case '<':
|
||||
/* 0 < sig is handled like sig > 0. */
|
||||
if (! rcon) {
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
@@ -257,7 +257,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
/* Handle the special case of a single bit equality
|
||||
operation. Make an XNOR gate instead of a comparator. */
|
||||
if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XNOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -270,7 +270,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
operation. This is similar to single bit equality, but uses
|
||||
an XOR instead of an XNOR gate. */
|
||||
if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -349,7 +349,7 @@ NetNet* NetEBMult::synthesize(Design*des)
|
||||
connect(mult->pin_DataA(idx), lsig->pin(idx));
|
||||
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(mult->pin_DataB(idx), lsig->pin(idx));
|
||||
connect(mult->pin_DataB(idx), rsig->pin(idx));
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
@@ -363,10 +363,61 @@ NetNet* NetEBMult::synthesize(Design*des)
|
||||
|
||||
NetNet* NetEBDiv::synthesize(Design*des)
|
||||
{
|
||||
cerr << get_line() << ": internal error: cannot synthesize division: "
|
||||
<< *this << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
switch (op()) {
|
||||
|
||||
case '/': {
|
||||
NetDivide*div = new NetDivide(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
break;
|
||||
}
|
||||
|
||||
case '%': {
|
||||
NetModulo*div = new NetModulo(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "NetEBDiv has unexpeced op() code: "
|
||||
<< op() << endl;
|
||||
des->errors += 1;
|
||||
|
||||
delete osig;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEBLogic::synthesize(Design*des)
|
||||
@@ -394,7 +445,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
comparison with a single wide OR gate. So handle this
|
||||
magically. */
|
||||
|
||||
string oname = scope->local_hsymbol();
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
NetLogic*olog = new NetLogic(scope, oname,
|
||||
lsig->pin_count()+rsig->pin_count()+1,
|
||||
@@ -418,7 +469,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
/* Create the logic AND gate. This is a single bit
|
||||
output, with inputs for each of the operands. */
|
||||
NetLogic*olog;
|
||||
string oname = scope->local_hsymbol();
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||
|
||||
@@ -436,7 +487,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
connect(lsig->pin(0), olog->pin(1));
|
||||
|
||||
assert(rsig->pin_count() == 1);
|
||||
connect(lsig->pin(0), olog->pin(2));
|
||||
connect(rsig->pin(0), olog->pin(2));
|
||||
}
|
||||
|
||||
|
||||
@@ -457,6 +508,9 @@ NetNet* NetEBShift::synthesize(Design*des)
|
||||
if (lsig == 0)
|
||||
return 0;
|
||||
|
||||
bool right_flag = op_ == 'r' || op_ == 'R';
|
||||
bool signed_flag = op_ == 'R';
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
|
||||
/* Detect the special case where the shift amount is
|
||||
@@ -515,7 +569,8 @@ NetNet* NetEBShift::synthesize(Design*des)
|
||||
assert(op() == 'l');
|
||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||
osig->pin_count(),
|
||||
rsig->pin_count());
|
||||
rsig->pin_count(),
|
||||
right_flag, signed_flag);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
|
||||
@@ -528,14 +583,6 @@ NetNet* NetEBShift::synthesize(Design*des)
|
||||
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1)
|
||||
connect(dev->pin_Distance(idx), rsig->pin(idx));
|
||||
|
||||
verinum dir_v = (op() == 'r')? verinum::V1 : verinum::V0;
|
||||
NetNet*dir_n = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetConst*dir = new NetConst(scope, scope->local_symbol(), dir_v);
|
||||
des->add_node(dir);
|
||||
connect(dev->pin_Direction(), dir->pin(0));
|
||||
connect(dev->pin_Direction(), dir_n->pin(0));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
@@ -551,7 +598,7 @@ NetNet* NetEConcat::synthesize(Design*des)
|
||||
assert(scope);
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
string path = scope->local_symbol();
|
||||
perm_string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
@@ -579,11 +626,12 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
|
||||
string path = scope->local_symbol();
|
||||
perm_string path = scope->local_symbol();
|
||||
unsigned width=expr_width();
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
osig->set_signed(has_sign());
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1)
|
||||
connect(osig->pin(idx), con->pin(idx));
|
||||
@@ -616,7 +664,7 @@ NetNet* NetEUBits::synthesize(Design*des)
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
|
||||
string oname = scope->local_hsymbol();
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -647,7 +695,7 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = scope->local_hsymbol();
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -746,7 +794,7 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||
NetNet*tsig = true_val_->synthesize(des);
|
||||
NetNet*fsig = false_val_->synthesize(des);
|
||||
|
||||
string path = csig->scope()->local_symbol();
|
||||
perm_string path = csig->scope()->local_symbol();
|
||||
|
||||
assert(csig->pin_count() == 1);
|
||||
|
||||
@@ -761,7 +809,7 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||
assert(width <= tsig->pin_count());
|
||||
assert(width <= fsig->pin_count());
|
||||
|
||||
string oname = csig->scope()->local_symbol();
|
||||
perm_string oname = csig->scope()->local_symbol();
|
||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
||||
@@ -815,7 +863,7 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||
NetScope*scope = net_->scope();
|
||||
assert(scope);
|
||||
|
||||
string name = scope->local_symbol();
|
||||
perm_string name = scope->local_symbol();
|
||||
NetNet*tmp = new NetNet(scope, name, NetNet::WIRE, wid);
|
||||
tmp->local_flag(true);
|
||||
|
||||
@@ -827,6 +875,27 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: expr_synth.cc,v $
|
||||
* Revision 1.59 2004/06/30 02:16:26 steve
|
||||
* Implement signed divide and signed right shift in nets.
|
||||
*
|
||||
* Revision 1.58 2004/06/16 16:21:34 steve
|
||||
* Connect rsif of multiply to DataB.
|
||||
*
|
||||
* Revision 1.57 2004/06/12 15:00:02 steve
|
||||
* Support / and % in synthesized contexts.
|
||||
*
|
||||
* Revision 1.56 2004/06/01 01:04:57 steve
|
||||
* Fix synthesis method for logical and/or
|
||||
*
|
||||
* Revision 1.55 2004/02/20 18:53:35 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.54 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.53 2004/02/15 04:23:48 steve
|
||||
* Fix evaluation of compare to constant expression.
|
||||
*
|
||||
* Revision 1.52 2003/11/10 19:39:20 steve
|
||||
* Remove redundant scope tokens.
|
||||
*
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -114,7 +114,7 @@ void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
void Design::functor(functor_t*fun)
|
||||
{
|
||||
// Scan 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)->run_functor(this, fun);
|
||||
|
||||
@@ -267,6 +267,9 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.32 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.31 2002/08/16 05:18:27 steve
|
||||
* Fix intermix of node functors and node delete.
|
||||
*
|
||||
|
||||
+8
-8
@@ -103,7 +103,7 @@ fi
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
@@ -112,7 +112,7 @@ if [ x"$dir_arg" != x ]; then
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
@@ -122,7 +122,7 @@ else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
@@ -150,7 +150,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
@@ -189,17 +189,17 @@ else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
@@ -230,7 +230,7 @@ else
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
.TH iverilog-vpi 1 "$Date: 2003/10/14 00:40:06 $" Version "$Date: 2003/10/14 00:40:06 $"
|
||||
.TH iverilog-vpi 1 "$Date: 2004/10/04 01:10:53 $" Version "$Date: 2004/10/04 01:10:53 $"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
@@ -118,5 +118,5 @@ iverilog(1), vvp(1),
|
||||
.nf
|
||||
Copyright \(co 2002 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
|
||||
|
||||
+8
-3
@@ -17,7 +17,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: iverilog-vpi.sh,v 1.13 2003/10/14 18:05:18 steve Exp $"
|
||||
#ident "$Id: iverilog-vpi.sh,v 1.14 2004/05/20 00:40:34 steve Exp $"
|
||||
|
||||
# These are the variables used for compiling files
|
||||
CC=gcc
|
||||
@@ -45,6 +45,7 @@ CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
OUT=
|
||||
INCOPT=
|
||||
|
||||
# --
|
||||
# parse the command line switches. This collects the source files
|
||||
@@ -80,6 +81,10 @@ do
|
||||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
-I*) INCOPT="$INCOPT $parm"
|
||||
echo "$parm"
|
||||
;;
|
||||
|
||||
-m32) LDFLAGS="-m32 $LDFLAGS32"
|
||||
CFLAGS="-m32 $CFLAGS"
|
||||
INSTDIR="$INSTDIR32"
|
||||
@@ -125,7 +130,7 @@ do
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CC -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
$CC -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
@@ -135,7 +140,7 @@ do
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CXX -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
$CXX -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
|
||||
+20
-11
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_target.h,v 1.124 2003/12/03 02:46:24 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.126 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -48,7 +48,7 @@ _BEGIN_DECL
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* In order to grab onto data in the design, the core passes cookies
|
||||
* to the various functions of the module. These cookies can in turn
|
||||
* be passed to access functions in the core to get more detailed
|
||||
@@ -380,7 +380,7 @@ extern const char* ivl_design_flag(ivl_design_t des, const char*key);
|
||||
extern int ivl_design_process(ivl_design_t des,
|
||||
ivl_process_f fun, void*cd);
|
||||
extern ivl_scope_t ivl_design_root(ivl_design_t des);
|
||||
extern void ivl_design_roots(ivl_design_t des,
|
||||
extern void ivl_design_roots(ivl_design_t des,
|
||||
ivl_scope_t **scopes,
|
||||
unsigned int *nscopes);
|
||||
extern int ivl_design_time_precision(ivl_design_t des);
|
||||
@@ -563,6 +563,9 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
|
||||
*
|
||||
* ivl_logic_pins
|
||||
* ivl_logic_pin
|
||||
* Return the nexus for the pin. If two pins are connected
|
||||
* together, then these values are the same. Use the nexus
|
||||
* functions to find other pins that are connected to this nexus.
|
||||
*
|
||||
* ivl_logic_attr (obsolete)
|
||||
* Return the value of a specific attribute, given the key name as
|
||||
@@ -591,7 +594,7 @@ extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net);
|
||||
extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx);
|
||||
|
||||
/* UDP
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
extern unsigned ivl_udp_sequ(ivl_udp_t net);
|
||||
@@ -644,7 +647,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
||||
* output vector. This is most devices, it turns out.
|
||||
*
|
||||
* ivl_lpm_selects
|
||||
* This is the size of the select input for a LPM_MUX device, or the
|
||||
* This is the size of the select input for a LPM_MUX device, or the
|
||||
* address bus width of an LPM_RAM.
|
||||
*
|
||||
* ivl_lpm_signed
|
||||
@@ -717,9 +720,9 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
||||
* returns an ivl_expr_t that represents that
|
||||
* expression. Otherwise, it returns 0.
|
||||
*
|
||||
* ivl_lval_mem
|
||||
* ivl_lval_mem
|
||||
* If the l-value is a memory, this method returns an
|
||||
* ivl_memory_t that represents that memory. Otherwise, it
|
||||
* ivl_memory_t that represents that memory. Otherwise, it
|
||||
* returns 0.
|
||||
*
|
||||
* ivl_lval_sig
|
||||
@@ -736,9 +739,9 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
||||
* The part select of the signal is based here. This is the
|
||||
* canonical index of bit-0 of the part select.
|
||||
*
|
||||
* ivl_lval_idx
|
||||
* ivl_lval_idx
|
||||
* If the l-value is a memory, this method returns an
|
||||
* ivl_expr_t that represents the index expression. Otherwise, it
|
||||
* ivl_expr_t that represents the index expression. Otherwise, it
|
||||
* returns 0.
|
||||
*
|
||||
* ivl_lval_pin
|
||||
@@ -761,7 +764,7 @@ extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
|
||||
* connections of signals and nodes is handled by single-bit
|
||||
* nexus. These functions manage the ivl_nexus_t object. They also
|
||||
* manage the ivl_nexus_ptr_t objects that are closely related to the
|
||||
* nexus.
|
||||
* nexus.
|
||||
*
|
||||
* ivl_nexus_name
|
||||
* Each nexus is given a name, typically derived from the signals
|
||||
@@ -941,7 +944,7 @@ extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
|
||||
* Every scope has a hierarchical name. This name is also a prefix
|
||||
* of all the names of objects contained within the scope. The
|
||||
* ivl_scope_basename is the name of the scope without the included
|
||||
* hierarchy.
|
||||
* hierarchy.
|
||||
*
|
||||
* ivl_scope_param
|
||||
* ivl_scope_params
|
||||
@@ -1233,6 +1236,12 @@ _END_DECL
|
||||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.126 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.125 2004/09/25 01:58:12 steve
|
||||
* Some commentary on ivl_logic_pin.
|
||||
*
|
||||
* Revision 1.124 2003/12/03 02:46:24 steve
|
||||
* Add support for wait on list of named events.
|
||||
*
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.15 2003/09/05 18:04:16 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.17 2004/10/04 01:10:56 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -40,9 +40,9 @@ INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I.. -I$(srcdir)/.. -I$(srcdir)
|
||||
LDFLAGS = @LDFLAGS@
|
||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: ivlpp
|
||||
|
||||
|
||||
+3
-3
@@ -1,17 +1,17 @@
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
+8
-5
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: lexor.lex,v 1.42 2003/09/26 02:08:31 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.46 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -30,6 +30,7 @@
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
# include <assert.h>
|
||||
|
||||
# include "parse.h"
|
||||
@@ -90,7 +91,8 @@ static void ifdef_enter(void)
|
||||
{
|
||||
struct ifdef_stack_t*cur;
|
||||
|
||||
cur = calloc(1, sizeof(struct ifdef_stack_t));
|
||||
cur = (struct ifdef_stack_t*)
|
||||
calloc(1, sizeof(struct ifdef_stack_t));
|
||||
cur->path = strdup(istack->path);
|
||||
cur->lineno = istack->lineno;
|
||||
cur->next = ifdef_stack;
|
||||
@@ -390,7 +392,8 @@ static void def_match()
|
||||
return;
|
||||
}
|
||||
|
||||
isp = calloc(1, sizeof(struct include_stack_t));
|
||||
isp = (struct include_stack_t*)
|
||||
calloc(1, sizeof(struct include_stack_t));
|
||||
isp->str = cur->value;
|
||||
isp->next = istack;
|
||||
istack->yybs = YY_CURRENT_BUFFER;
|
||||
@@ -552,7 +555,7 @@ static int def_is_done()
|
||||
/*
|
||||
* After some number of calls to do_define, this function is called to
|
||||
* assigned value to the parsed name. If there is no value, then
|
||||
* assign the string "1"
|
||||
* assign the string "" (empty string.)
|
||||
*/
|
||||
static void def_finish()
|
||||
{
|
||||
@@ -566,7 +569,7 @@ static void def_finish()
|
||||
define_cnt = 0;
|
||||
|
||||
} else {
|
||||
define_macro(def_name, "1", 0);
|
||||
define_macro(def_name, "", 0);
|
||||
}
|
||||
def_name[0] = 0;
|
||||
}
|
||||
|
||||
+13
-2
@@ -17,7 +17,7 @@ const char COPYRIGHT[] =
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.c,v 1.17 2003/09/26 02:08:31 steve Exp $"
|
||||
#ident "$Id: main.c,v 1.20 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -47,6 +47,7 @@ const char VERSION[] = "$Name: $ $State: Exp $";
|
||||
#endif
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
@@ -176,7 +177,8 @@ int main(int argc, char*argv[])
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*));
|
||||
include_dir = realloc(include_dir,
|
||||
(include_cnt+1)*sizeof(char*));
|
||||
include_dir[include_cnt] = strdup(optarg);
|
||||
include_cnt += 1;
|
||||
break;
|
||||
@@ -288,6 +290,15 @@ int main(int argc, char*argv[])
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.20 2004/09/10 00:15:45 steve
|
||||
* Remove bad casts.
|
||||
*
|
||||
* Revision 1.19 2004/09/05 21:29:08 steve
|
||||
* Better type safety.
|
||||
*
|
||||
* Revision 1.18 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.17 2003/09/26 02:08:31 steve
|
||||
* Detect missing endif markers.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: lexor.lex,v 1.85 2003/08/31 21:14:28 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.86 2004/06/13 04:56:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -98,6 +98,7 @@ static int comment_enter;
|
||||
%x CSTRING
|
||||
%s UDPTABLE
|
||||
%x PPTIMESCALE
|
||||
%x PPDEFAULT_NETTYPE
|
||||
|
||||
W [ \t\b\f\r]+
|
||||
|
||||
@@ -269,7 +270,6 @@ W [ \t\b\f\r]+
|
||||
should handle these, not an external preprocessor. */
|
||||
|
||||
^{W}?`celldefine{W}?.* { }
|
||||
^{W}?`default_nettype{W}?.* { }
|
||||
^{W}?`delay_mode_distributed{W}?.* { }
|
||||
^{W}?`delay_mode_unit{W}?.* { }
|
||||
^{W}?`delay_mode_path{W}?.* { }
|
||||
@@ -285,6 +285,36 @@ W [ \t\b\f\r]+
|
||||
^{W}?`unconnected_drive{W}?.* { }
|
||||
^{W}?`uselib{W}?.* { }
|
||||
|
||||
/* Notice and handle the default_nettype directive. The lexor
|
||||
detects the default_nettype keyword, and the second part of the
|
||||
rule collects the rest of the line and processes it. We only need
|
||||
to look for the first work, and interpret it. */
|
||||
|
||||
`default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
|
||||
<PPDEFAULT_NETTYPE>.* {
|
||||
NetNet::Type net_type;
|
||||
size_t wordlen = strcspn(yytext, " \t\f\r\n");
|
||||
yytext[wordlen] = 0;
|
||||
if (strcmp(yytext,"wire") == 0) {
|
||||
net_type = NetNet::WIRE;
|
||||
|
||||
} else if (strcmp(yytext,"none") == 0) {
|
||||
net_type = NetNet::NONE;
|
||||
|
||||
} else {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line
|
||||
<< " error: Net type " << yytext
|
||||
<< " is not a valid (and supported)"
|
||||
<< " default net type." << endl;
|
||||
net_type = NetNet::WIRE;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
|
||||
}
|
||||
<PPDEFAULT_NETTYPE>\n {
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
|
||||
/* These are directives that are not supported by me and should have
|
||||
been handled by an external preprocessor such as ivlpp. */
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.31 2003/10/10 02:57:45 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.34 2004/10/04 01:10:07 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -33,15 +33,13 @@ libdir = @libdir@
|
||||
libdir64 = @libdir64@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
CC = @CC@ -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
CXX = @CXX@ -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
STRIP = @STRIP@
|
||||
RANLIB = @RANLIB@
|
||||
@@ -86,12 +84,12 @@ dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep libveriuser.a libveriuser.o
|
||||
rm -rf *.o dep libveriuser.a libveriuser.o bin32
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
@@ -114,7 +112,7 @@ bin32:
|
||||
mkdir bin32
|
||||
|
||||
bin32/%.o: %.c
|
||||
$(CC) -m32 -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
|
||||
$(CC) -m32 $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
|
||||
|
||||
bin32/libveriuser.o: $(addprefix bin32/,$O)
|
||||
$(LD) -melf_i386 -r -o $@ $(addprefix bin32/,$O)
|
||||
|
||||
@@ -17,19 +17,22 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_compare_handles.c,v 1.2 2003/08/26 16:26:02 steve Exp $"
|
||||
#ident "$Id: a_compare_handles.c,v 1.3 2004/02/18 02:51:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <acc_user.h>
|
||||
|
||||
int acc_compare_handles(handle handle1, handle handle2)
|
||||
PLI_INT32 acc_compare_handles(handle handle1, handle handle2)
|
||||
{
|
||||
return handle1 == handle2;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_compare_handles.c,v $
|
||||
* Revision 1.3 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.2 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_configure.c,v 1.3 2003/06/17 16:55:07 steve Exp $"
|
||||
#ident "$Id: a_configure.c,v 1.4 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <acc_user.h>
|
||||
#include <vpi_user.h>
|
||||
#include "priv.h"
|
||||
#include <string.h>
|
||||
|
||||
int acc_configure(PLI_INT32 config_param, const char*value)
|
||||
{
|
||||
@@ -39,6 +40,32 @@ int acc_configure(PLI_INT32 config_param, const char*value)
|
||||
}
|
||||
break;
|
||||
|
||||
case accEnableArgs:
|
||||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_configure(accEnableArgs, %s)\n",
|
||||
value);
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
if (strcmp(value,"acc_set_scope") == 0) {
|
||||
vpi_printf("XXXX acc_configure argument: Sorry: "
|
||||
"(accEnableArgs, %s\n", value);
|
||||
rc = 0;
|
||||
|
||||
} else if (strcmp(value,"no_acc_set_scope") == 0) {
|
||||
vpi_printf("XXXX acc_configure argument: Sorry: "
|
||||
"(accEnableArgs, %s\n", value);
|
||||
rc = 0;
|
||||
|
||||
} else {
|
||||
vpi_printf("XXXX acc_configure argument error. "
|
||||
"(accEnableArgs, %s(invalid)\n", value);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (pli_trace) {
|
||||
@@ -56,6 +83,9 @@ int acc_configure(PLI_INT32 config_param, const char*value)
|
||||
|
||||
/*
|
||||
* $Log: a_configure.c,v $
|
||||
* Revision 1.4 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.3 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_range.c,v 1.1 2003/06/04 01:56:20 steve Exp $"
|
||||
#ident "$Id: a_fetch_range.c,v 1.2 2004/02/18 02:51:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
@@ -26,7 +26,7 @@
|
||||
/*
|
||||
* acc_fetch_range implemented using VPI interface
|
||||
*/
|
||||
PLI_INT32 acc_fetch_range(handle object, PLI_INT32 *msb, PLI_INT32 *lsb)
|
||||
PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb)
|
||||
{
|
||||
*msb = vpi_get(vpiLeftRange, object);
|
||||
*lsb = vpi_get(vpiRightRange, object);
|
||||
@@ -35,6 +35,9 @@ PLI_INT32 acc_fetch_range(handle object, PLI_INT32 *msb, PLI_INT32 *lsb)
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_range.c,v $
|
||||
* Revision 1.2 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.1 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
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_tfarg.c,v 1.8 2003/06/14 01:16:17 steve Exp $"
|
||||
#ident "$Id: a_fetch_tfarg.c,v 1.10 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
@@ -42,7 +42,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
|
||||
if (hand) {
|
||||
value.format=vpiRealVal;
|
||||
vpi_get_value(hand, &value);
|
||||
rtn = value.value.real;
|
||||
rtn = value.value.real;
|
||||
vpi_free_object(iter);
|
||||
} else {
|
||||
rtn = 0.0;
|
||||
@@ -56,7 +56,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
|
||||
return rtn;
|
||||
}
|
||||
|
||||
double acc_fetch_tfarg(int n)
|
||||
double acc_fetch_tfarg(PLI_INT32 n)
|
||||
{
|
||||
return acc_fetch_itfarg_int(n, vpi_handle(vpiSysTfCall,0));
|
||||
}
|
||||
@@ -77,7 +77,7 @@ PLI_INT32 acc_fetch_itfarg_int(PLI_INT32 n, handle obj)
|
||||
if (hand) {
|
||||
value.format=vpiIntVal;
|
||||
vpi_get_value(hand, &value);
|
||||
rtn = value.value.integer;
|
||||
rtn = value.value.integer;
|
||||
vpi_free_object(iter);
|
||||
} else {
|
||||
rtn = 0;
|
||||
@@ -134,6 +134,12 @@ char *acc_fetch_tfarg_str(PLI_INT32 n)
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_tfarg.c,v $
|
||||
* Revision 1.10 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.9 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.8 2003/06/14 01:16:17 steve
|
||||
* ihand is system task, not scope.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_type.c,v 1.7 2003/06/04 01:56:20 steve Exp $"
|
||||
#ident "$Id: a_fetch_type.c,v 1.8 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <acc_user.h>
|
||||
@@ -78,7 +78,7 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
|
||||
type = vpi_get(vpiNetType, obj);
|
||||
switch(type) {
|
||||
case vpiWire: return accWire;
|
||||
default:
|
||||
default:
|
||||
vpi_printf("acc_fetch_fulltype: vpiNetType %d unknown?\n",
|
||||
type);
|
||||
return accUnknown;
|
||||
@@ -121,6 +121,9 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_type.c,v $
|
||||
* Revision 1.8 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.7 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
|
||||
|
||||
@@ -17,24 +17,47 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_handle_object.c,v 1.1 2003/03/13 04:35:09 steve Exp $"
|
||||
#ident "$Id: a_handle_object.c,v 1.2 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
#include <acc_user.h>
|
||||
#include "priv.h"
|
||||
|
||||
static vpiHandle search_scope = 0;
|
||||
|
||||
handle acc_handle_object(const char*name)
|
||||
{
|
||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle scope = vpi_handle(vpiScope, sys);
|
||||
|
||||
vpiHandle scope = search_scope? search_scope : vpi_handle(vpiScope, sys);
|
||||
vpiHandle res = vpi_handle_by_name(name, scope);
|
||||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_handle_object(%s <scope=%s>) --> .\n",
|
||||
name, acc_fetch_fullname(scope));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
char* acc_set_scope(handle ref, ...)
|
||||
{
|
||||
char*name;
|
||||
search_scope = ref;
|
||||
|
||||
name = acc_fetch_fullname(search_scope);
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_set_scope(<scope=%s>)\n", name);
|
||||
}
|
||||
|
||||
return acc_fetch_fullname(ref);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_handle_object.c,v $
|
||||
* Revision 1.2 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.1 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_handle_tfarg.c,v 1.5 2003/03/18 01:21:49 steve Exp $"
|
||||
#ident "$Id: a_handle_tfarg.c,v 1.6 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <acc_user.h>
|
||||
@@ -29,7 +29,7 @@
|
||||
handle acc_handle_tfarg(int n)
|
||||
{
|
||||
vpiHandle sys_h, sys_i, rtn_h = 0;
|
||||
|
||||
|
||||
if (n > 0) {
|
||||
sys_h = vpi_handle(vpiSysTfCall, 0 /* NULL */);
|
||||
sys_i = vpi_iterate(vpiArgument, sys_h);
|
||||
@@ -58,6 +58,9 @@ handle acc_handle_tfinst(void)
|
||||
|
||||
/*
|
||||
* $Log: a_handle_tfarg.c,v $
|
||||
* Revision 1.6 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.5 2003/03/18 01:21:49 steve
|
||||
* Fix warning about uninitialized variable.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_object_of_type.c,v 1.5 2003/06/04 01:56:20 steve Exp $"
|
||||
#ident "$Id: a_object_of_type.c,v 1.6 2004/02/18 02:51:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
@@ -28,7 +28,7 @@
|
||||
/*
|
||||
* acc_object_of_type implemented using VPI interface
|
||||
*/
|
||||
PLI_INT32 acc_object_of_type(handle object, PLI_INT32 type)
|
||||
int acc_object_of_type(handle object, PLI_INT32 type)
|
||||
{
|
||||
int vtype;
|
||||
int rtn = 0; /* false */
|
||||
@@ -86,7 +86,7 @@ PLI_INT32 acc_object_of_type(handle object, PLI_INT32 type)
|
||||
return rtn;
|
||||
}
|
||||
|
||||
PLI_INT32 acc_object_in_typelist(handle object, PLI_INT32*typelist)
|
||||
int acc_object_in_typelist(handle object, PLI_INT32*typelist)
|
||||
{
|
||||
while (typelist[0] != 0) {
|
||||
int rtn = acc_object_of_type(object, typelist[0]);
|
||||
@@ -101,6 +101,9 @@ PLI_INT32 acc_object_in_typelist(handle object, PLI_INT32*typelist)
|
||||
|
||||
/*
|
||||
* $Log: a_object_of_type.c,v $
|
||||
* Revision 1.6 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.5 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
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_vcl.c,v 1.6 2003/06/17 16:55:07 steve Exp $"
|
||||
#ident "$Id: a_vcl.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
@@ -154,7 +154,7 @@ static PLI_INT32 vcl_value_callback(struct t_cb_data*cb)
|
||||
vcr.vc_hightime = sim_time.high;
|
||||
vcr.vc_lowtime = sim_time.low;
|
||||
vcr.user_data = cur->user_data;
|
||||
|
||||
|
||||
(cur->consumer) (&vcr);
|
||||
return 0;
|
||||
}
|
||||
@@ -206,6 +206,9 @@ void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
||||
|
||||
/*
|
||||
* $Log: a_vcl.c,v $
|
||||
* Revision 1.7 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.6 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
|
||||
@@ -5,8 +5,8 @@ AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AX_CPP_IDENT
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
@@ -18,30 +18,11 @@ AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
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)
|
||||
# may modify CPPFLAGS and CFLAGS
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Compiler option for position independent code, needed whan making shared objects.
|
||||
AX_C_PICFLAG
|
||||
|
||||
AC_SUBST(EXEEXT)
|
||||
AC_SUBST(EXTRALIBS)
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: getp.c,v 1.6 2003/06/17 16:55:07 steve Exp $"
|
||||
#ident "$Id: getp.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <assert.h>
|
||||
@@ -158,7 +158,7 @@ char *tf_istrgetp(PLI_INT32 n, PLI_INT32 fmt, void *obj)
|
||||
case 'd': value.format = vpiDecStrVal; break;
|
||||
case 'h': value.format = vpiHexStrVal; break;
|
||||
}
|
||||
if (value.format > 0) {
|
||||
if (value.format > 0) {
|
||||
vpi_get_value(arg_h, &value);
|
||||
rtn = value.value.str;
|
||||
}
|
||||
@@ -184,6 +184,9 @@ char *tf_strgetp(PLI_INT32 n, PLI_INT32 fmt)
|
||||
|
||||
/*
|
||||
* $Log: getp.c,v $
|
||||
* Revision 1.7 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.6 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: putlongp.c,v 1.3 2003/03/15 05:42:39 steve Exp $"
|
||||
#ident "$Id: putlongp.c,v 1.4 2004/09/10 23:13:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -58,13 +58,16 @@ void tf_putlongp(int n, int lowvalue, int highvalue)
|
||||
sprintf(str, "%x%08x", highvalue, lowvalue);
|
||||
val.format = vpiHexStrVal;
|
||||
val.value.str = str;
|
||||
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
|
||||
vpi_free_object(sys_i);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: putlongp.c,v $
|
||||
* Revision 1.4 2004/09/10 23:13:05 steve
|
||||
* Compile cleanup of C code.
|
||||
*
|
||||
* Revision 1.3 2003/03/15 05:42:39 steve
|
||||
* free argument iterators.
|
||||
*
|
||||
|
||||
+6
-3
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: putp.c,v 1.6 2003/06/26 03:20:24 steve Exp $"
|
||||
#ident "$Id: putp.c,v 1.7 2004/09/10 23:13:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <assert.h>
|
||||
@@ -74,7 +74,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
|
||||
/* fill in vpi_value */
|
||||
val.format = vpiIntVal;
|
||||
val.value.integer = value;
|
||||
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
|
||||
if (arg_h)
|
||||
vpi_free_object(sys_i);
|
||||
@@ -123,7 +123,7 @@ PLI_INT32 tf_iputrealp(PLI_INT32 n, double value, void *obj)
|
||||
/* fill in vpi_value */
|
||||
val.format = vpiRealVal;
|
||||
val.value.real = value;
|
||||
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
|
||||
|
||||
free:
|
||||
vpi_free_object(sys_i);
|
||||
@@ -145,6 +145,9 @@ PLI_INT32 tf_putrealp(PLI_INT32 n, double value)
|
||||
}
|
||||
/*
|
||||
* $Log: putp.c,v $
|
||||
* Revision 1.7 2004/09/10 23:13:05 steve
|
||||
* Compile cleanup of C code.
|
||||
*
|
||||
* Revision 1.6 2003/06/26 03:20:24 steve
|
||||
* Correct handle of put to function return value.
|
||||
*
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: veriusertfs.c,v 1.14 2003/06/25 04:04:19 steve Exp $"
|
||||
#ident "$Id: veriusertfs.c,v 1.15 2004/09/10 23:13:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -84,7 +84,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||
}
|
||||
|
||||
/* squirrel away veriusertfs in persistent user_data */
|
||||
data = (p_pli_data) calloc(1, sizeof(s_pli_data));
|
||||
data = calloc(1, sizeof(s_pli_data));
|
||||
assert(data != NULL);
|
||||
data->tf = tf;
|
||||
|
||||
@@ -92,7 +92,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||
it to the pli_data that represents this
|
||||
function. Supply wrapper functions for the system
|
||||
task actions. */
|
||||
(void) memset(&tf_data, 0, sizeof(s_vpi_systf_data));
|
||||
memset(&tf_data, 0, sizeof(s_vpi_systf_data));
|
||||
switch (tf->type) {
|
||||
case usertask:
|
||||
tf_data.type = vpiSysTask;
|
||||
@@ -164,7 +164,7 @@ static int compiletf(char *data)
|
||||
vpi_put_userdata(call_h, pli);
|
||||
|
||||
/* default cb_data */
|
||||
(void) memset(&cb_data, 0, sizeof(s_cb_data));
|
||||
memset(&cb_data, 0, sizeof(s_cb_data));
|
||||
cb_data.cb_rtn = callback;
|
||||
cb_data.user_data = data;
|
||||
|
||||
@@ -182,7 +182,7 @@ static int compiletf(char *data)
|
||||
cb_data.reason = cbValueChange;
|
||||
while ((arg_h = vpi_scan(arg_i)) != NULL) {
|
||||
/* replicate user_data for each instance */
|
||||
dp = (p_pli_data)calloc(1, sizeof(s_pli_data));
|
||||
dp = calloc(1, sizeof(s_pli_data));
|
||||
assert(dp != NULL);
|
||||
memcpy(dp, cb_data.user_data, sizeof(s_pli_data));
|
||||
dp->paramvc = paramvc++;
|
||||
@@ -389,6 +389,9 @@ PLI_INT32 tf_setrealdelay(double dly)
|
||||
}
|
||||
/*
|
||||
* $Log: veriusertfs.c,v $
|
||||
* Revision 1.15 2004/09/10 23:13:05 steve
|
||||
* Compile cleanup of C code.
|
||||
*
|
||||
* Revision 1.14 2003/06/25 04:04:19 steve
|
||||
* Fix mingw portability problems.
|
||||
*
|
||||
|
||||
+5
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: link_const.cc,v 1.16 2003/06/21 01:21:43 steve Exp $"
|
||||
#ident "$Id: link_const.cc,v 1.17 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -59,7 +59,7 @@ bool Nexus::drivers_constant() const
|
||||
outside world. */
|
||||
|
||||
if (cur_dir == Link::PASSIVE) {
|
||||
|
||||
|
||||
const NetObj*obj = cur->get_obj();
|
||||
if (obj->scope()->parent() != 0)
|
||||
continue;
|
||||
@@ -164,6 +164,9 @@ verinum::V Nexus::driven_value() const
|
||||
|
||||
/*
|
||||
* $Log: link_const.cc,v $
|
||||
* Revision 1.17 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.16 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ quite similar.
|
||||
lexor_keyword.gperf, and use that.
|
||||
|
||||
3) If working with a CVS snapshot, you must run autoconf in several
|
||||
directories. This is aided by the 'autoconf.sh' script at the
|
||||
directories. This is aided by the 'autoconf.sh' script at the
|
||||
top of the source tree:
|
||||
|
||||
sh ./autoconf.sh
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1998-2003 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 1998-2004 Stephen Williams ([email protected])";
|
||||
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -19,7 +19,7 @@ const char COPYRIGHT[] =
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.cc,v 1.79 2003/11/26 01:37:14 steve Exp $"
|
||||
#ident "$Id: main.cc,v 1.86 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -86,11 +86,11 @@ generation_t generation_flag = GN_DEFAULT;
|
||||
map<string,const char*> flags;
|
||||
char*vpi_module_list = 0;
|
||||
|
||||
map<string,unsigned> missing_modules;
|
||||
map<perm_string,unsigned> missing_modules;
|
||||
|
||||
list<const char*> library_suff;
|
||||
|
||||
list<const char*> roots;
|
||||
list<perm_string> roots;
|
||||
|
||||
char*ivlpp_string = 0;
|
||||
|
||||
@@ -106,6 +106,12 @@ bool warn_portbinding = false;
|
||||
|
||||
bool error_implicit = false;
|
||||
|
||||
/*
|
||||
* Debug message class flags.
|
||||
*/
|
||||
bool debug_scopes = false;
|
||||
bool debug_eval_tree = false;
|
||||
bool debug_elaborate = false;
|
||||
/*
|
||||
* Verbose messages enabled.
|
||||
*/
|
||||
@@ -228,6 +234,9 @@ static void parm_to_flagmap(const string&flag)
|
||||
* basedir:<path>
|
||||
* Location to look for installed sub-components
|
||||
*
|
||||
* debug:<name>
|
||||
* Activate a class of debug messages.
|
||||
*
|
||||
* depfile:<path>
|
||||
* Give the path to an output dependency file.
|
||||
*
|
||||
@@ -250,6 +259,9 @@ static void parm_to_flagmap(const string&flag)
|
||||
* out:<path>
|
||||
* Path to the output file.
|
||||
*
|
||||
* sys_func:<path>
|
||||
* Path to a system functions descriptor table
|
||||
*
|
||||
* root:<name>
|
||||
* Specify a root module. There may be multiple of this.
|
||||
*
|
||||
@@ -292,6 +304,19 @@ static void read_iconfig_file(const char*ipath)
|
||||
if (strcmp(buf, "basedir") == 0) {
|
||||
basedir = strdup(cp);
|
||||
|
||||
} else if (strcmp(buf, "debug") == 0) {
|
||||
if (strcmp(cp, "scope") == 0) {
|
||||
debug_scopes = true;
|
||||
cerr << "debug: Enable scope debug" << endl;
|
||||
} else if (strcmp(cp,"eval_tree") == 0) {
|
||||
debug_eval_tree = true;
|
||||
cerr << "debug: Enable eval_tree debug" << endl;
|
||||
} else if (strcmp(cp,"elaborate") == 0) {
|
||||
debug_elaborate = true;
|
||||
cerr << "debug: Enable elaborate debug" << endl;
|
||||
} else {
|
||||
}
|
||||
|
||||
} else if (strcmp(buf, "depfile") == 0) {
|
||||
depfile_name = strdup(cp);
|
||||
|
||||
@@ -333,8 +358,11 @@ static void read_iconfig_file(const char*ipath)
|
||||
} else if (strcmp(buf, "out") == 0) {
|
||||
flags["-o"] = strdup(cp);
|
||||
|
||||
} else if (strcmp(buf, "sys_func") == 0) {
|
||||
load_sys_func_table(cp);
|
||||
|
||||
} else if (strcmp(buf, "root") == 0) {
|
||||
roots.push_back(strdup(cp));
|
||||
roots.push_back(lex_strings.make(cp));
|
||||
|
||||
} else if (strcmp(buf,"warnings") == 0) {
|
||||
/* Scan the warnings enable string for warning flags. */
|
||||
@@ -384,19 +412,19 @@ static void read_iconfig_file(const char*ipath)
|
||||
}
|
||||
}
|
||||
|
||||
extern Design* elaborate(list <const char*>root);
|
||||
extern Design* elaborate(list <perm_string> root);
|
||||
|
||||
#if defined(HAVE_TIMES)
|
||||
static double cycles_diff(struct tms *a, struct tms *b)
|
||||
{
|
||||
clock_t aa = a->tms_utime
|
||||
+ a->tms_stime
|
||||
+ a->tms_cutime
|
||||
clock_t aa = a->tms_utime
|
||||
+ a->tms_stime
|
||||
+ a->tms_cutime
|
||||
+ a->tms_cstime;
|
||||
|
||||
clock_t bb = b->tms_utime
|
||||
+ b->tms_stime
|
||||
+ b->tms_cutime
|
||||
clock_t bb = b->tms_utime
|
||||
+ b->tms_stime
|
||||
+ b->tms_cutime
|
||||
+ b->tms_cstime;
|
||||
|
||||
return (aa-bb)/(double)sysconf(_SC_CLK_TCK);
|
||||
@@ -498,7 +526,7 @@ int main(int argc, char*argv[])
|
||||
perror(depfile_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag)
|
||||
@@ -526,13 +554,13 @@ int main(int argc, char*argv[])
|
||||
if (pf_path) {
|
||||
ofstream out (pf_path);
|
||||
out << "PFORM DUMP MODULES:" << endl;
|
||||
for (map<string,Module*>::iterator mod = pform_modules.begin()
|
||||
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
||||
; mod != pform_modules.end()
|
||||
; mod ++ ) {
|
||||
pform_dump(out, (*mod).second);
|
||||
}
|
||||
out << "PFORM DUMP PRIMITIVES:" << endl;
|
||||
for (map<string,PUdp*>::iterator idx = pform_primitives.begin()
|
||||
for (map<perm_string,PUdp*>::iterator idx = pform_primitives.begin()
|
||||
; idx != pform_primitives.end()
|
||||
; idx ++ ) {
|
||||
(*idx).second->dump(out);
|
||||
@@ -548,8 +576,8 @@ int main(int argc, char*argv[])
|
||||
then look for modules that are not instantiated anywhere. */
|
||||
|
||||
if (roots.empty()) {
|
||||
map<string,bool> mentioned_p;
|
||||
map<string,Module*>::iterator mod;
|
||||
map<perm_string,bool> mentioned_p;
|
||||
map<perm_string,Module*>::iterator mod;
|
||||
if (verbose_flag)
|
||||
cout << "LOCATING TOP-LEVEL MODULES" << endl << " ";
|
||||
for (mod = pform_modules.begin()
|
||||
@@ -578,7 +606,7 @@ int main(int argc, char*argv[])
|
||||
if (verbose_flag)
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
/* If there is *still* no guess for the root module, then give
|
||||
up completely, and complain. */
|
||||
|
||||
@@ -618,7 +646,7 @@ int main(int argc, char*argv[])
|
||||
des->set_flags(flags);
|
||||
|
||||
/* Done iwth all the pform data. Delete the modules. */
|
||||
for (map<string,Module*>::iterator idx = pform_modules.begin()
|
||||
for (map<perm_string,Module*>::iterator idx = pform_modules.begin()
|
||||
; idx != pform_modules.end() ; idx ++) {
|
||||
|
||||
delete (*idx).second;
|
||||
@@ -700,7 +728,7 @@ int main(int argc, char*argv[])
|
||||
if (missing_modules.size() > 0) {
|
||||
cerr << "*** These modules were missing:" << endl;
|
||||
|
||||
map<string,unsigned>::const_iterator idx;
|
||||
map<perm_string,unsigned>::const_iterator idx;
|
||||
for (idx = missing_modules.begin()
|
||||
; idx != missing_modules.end()
|
||||
; idx ++)
|
||||
@@ -711,11 +739,32 @@ int main(int argc, char*argv[])
|
||||
cerr << "***" << endl;
|
||||
}
|
||||
|
||||
return des->errors;
|
||||
return des? des->errors : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.cc,v $
|
||||
* Revision 1.86 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.85 2004/09/25 01:58:44 steve
|
||||
* Add a debug_elaborate flag
|
||||
*
|
||||
* Revision 1.84 2004/09/10 23:51:42 steve
|
||||
* Fix the evaluation of constant ternary expressions.
|
||||
*
|
||||
* Revision 1.83 2004/09/05 17:44:42 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.82 2004/03/10 04:51:24 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.81 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.80 2004/02/15 00:19:29 steve
|
||||
* Report elaboration errors without crashing.
|
||||
*
|
||||
* Revision 1.79 2003/11/26 01:37:14 steve
|
||||
* Properly initialize vpi_module_list with system.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __named_H
|
||||
#define __named_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-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
|
||||
@@ -19,10 +19,10 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: named.h,v 1.3 2002/08/12 01:34:59 steve Exp $"
|
||||
#ident "$Id: named.h,v 1.4 2004/02/20 06:22:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
* There are lots of places where names are attached to objects. This
|
||||
@@ -30,12 +30,15 @@
|
||||
*/
|
||||
|
||||
template <class T> struct named {
|
||||
string name;
|
||||
perm_string name;
|
||||
T parm;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: named.h,v $
|
||||
* Revision 1.4 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
+17
-36
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_assign.cc,v 1.16 2003/01/26 21:15:58 steve Exp $"
|
||||
#ident "$Id: net_assign.cc,v 1.18 2004/08/28 15:08:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -67,7 +67,7 @@ NetAssign_::~NetAssign_()
|
||||
{
|
||||
if (sig_) {
|
||||
sig_->decr_lref();
|
||||
if (sig_->peek_lref() == 0)
|
||||
if (turn_sig_to_wire_on_release_ && sig_->peek_lref() == 0)
|
||||
sig_->type(NetNet::WIRE);
|
||||
}
|
||||
|
||||
@@ -98,14 +98,14 @@ unsigned NetAssign_::lwidth() const
|
||||
else return lwid_;
|
||||
}
|
||||
|
||||
const char*NetAssign_::name() const
|
||||
perm_string NetAssign_::name() const
|
||||
{
|
||||
if (sig_) {
|
||||
return sig_->name();
|
||||
} else if (mem_) {
|
||||
return mem_->name();
|
||||
} else {
|
||||
return "";
|
||||
return perm_string::literal("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,13 @@ unsigned NetAssign_::get_loff() const
|
||||
return loff_;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
void NetAssign_::turn_sig_to_wire_on_release()
|
||||
{
|
||||
turn_sig_to_wire_on_release_ = true;
|
||||
}
|
||||
|
||||
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
|
||||
: lval_(lv), rval_(rv), delay_(0)
|
||||
{
|
||||
@@ -254,6 +261,12 @@ NetAssignNB::~NetAssignNB()
|
||||
|
||||
/*
|
||||
* $Log: net_assign.cc,v $
|
||||
* Revision 1.18 2004/08/28 15:08:31 steve
|
||||
* Do not change reg to wire in NetAssign_ unless synthesizing.
|
||||
*
|
||||
* Revision 1.17 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.16 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
@@ -289,37 +302,5 @@ NetAssignNB::~NetAssignNB()
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.8 2001/08/25 23:50:03 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.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.7 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.6 2000/10/18 20:04:39 steve
|
||||
* Add ivl_lval_t and support for assignment l-values.
|
||||
*
|
||||
* Revision 1.5 2000/09/20 02:53:15 steve
|
||||
* Correctly measure comples l-values of assignments.
|
||||
*
|
||||
* Revision 1.4 2000/09/10 02:18:16 steve
|
||||
* elaborate complex l-values
|
||||
*
|
||||
* Revision 1.3 2000/09/07 00:06:53 steve
|
||||
* encapsulate access to the l-value expected width.
|
||||
*
|
||||
* Revision 1.2 2000/09/02 23:40:13 steve
|
||||
* Pull NetAssign_ creation out of constructors.
|
||||
*
|
||||
* Revision 1.1 2000/09/02 20:54:20 steve
|
||||
* Rearrange NetAssign to make NetAssign_ separate.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+21
-11
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_design.cc,v 1.42 2003/11/10 20:59:03 steve Exp $"
|
||||
#ident "$Id: net_design.cc,v 1.45 2004/10/04 01:10:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
# include "netlist.h"
|
||||
# include "util.h"
|
||||
# include "compiler.h"
|
||||
# include <sstream>
|
||||
|
||||
Design:: Design()
|
||||
@@ -80,7 +81,7 @@ unsigned long Design::scale_to_precision(unsigned long val,
|
||||
return val;
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(const char*root)
|
||||
NetScope* Design::make_root_scope(perm_string root)
|
||||
{
|
||||
NetScope *root_scope_;
|
||||
root_scope_ = new NetScope(0, root, NetScope::MODULE);
|
||||
@@ -246,7 +247,7 @@ const NetExpr* Design::find_parameter(const NetScope*scope,
|
||||
*/
|
||||
void Design::run_defparams()
|
||||
{
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_defparams(this);
|
||||
}
|
||||
@@ -265,32 +266,32 @@ void NetScope::run_defparams(Design*des)
|
||||
NetExpr*val = (*pp).second;
|
||||
hname_t path = (*pp).first;
|
||||
|
||||
char*name = path.remove_tail_name();
|
||||
char*tmp = path.remove_tail_name();
|
||||
perm_string perm_name = lex_strings.make(tmp);
|
||||
delete[]tmp;
|
||||
|
||||
/* If there is no path on the name, then the targ_scope
|
||||
is the current scope. */
|
||||
NetScope*targ_scope = des->find_scope(this, path);
|
||||
if (targ_scope == 0) {
|
||||
cerr << val->get_line() << ": warning: scope of " <<
|
||||
path << "." << name << " not found." << endl;
|
||||
delete[]name;
|
||||
path << "." << perm_name << " not found." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool flag = targ_scope->replace_parameter(name, val);
|
||||
bool flag = targ_scope->replace_parameter(perm_name, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< name << " not found in "
|
||||
<< perm_name << " not found in "
|
||||
<< targ_scope->name() << "." << endl;
|
||||
}
|
||||
|
||||
delete[]name;
|
||||
}
|
||||
}
|
||||
|
||||
void Design::evaluate_parameters()
|
||||
{
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->evaluate_parameters(this);
|
||||
}
|
||||
@@ -309,7 +310,7 @@ void NetScope::evaluate_parameters(Design*des)
|
||||
// scanning code. Now the parameter expression can be fully
|
||||
// evaluated, or it cannot be evaluated at all.
|
||||
|
||||
typedef map<string,param_expr_t>::iterator mparm_it_t;
|
||||
typedef map<perm_string,param_expr_t>::iterator mparm_it_t;
|
||||
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
@@ -617,6 +618,15 @@ void Design::delete_process(NetProcTop*top)
|
||||
|
||||
/*
|
||||
* $Log: net_design.cc,v $
|
||||
* Revision 1.45 2004/10/04 01:10:54 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.44 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.43 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.42 2003/11/10 20:59:03 steve
|
||||
* Design::get_flag returns const char* instead of string.
|
||||
*
|
||||
|
||||
+17
-8
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_event.cc,v 1.23 2003/04/22 04:48:29 steve Exp $"
|
||||
#ident "$Id: net_event.cc,v 1.26 2004/10/04 01:10:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NOTE: The name_ is perm-allocated by the caller.
|
||||
*/
|
||||
NetEvent::NetEvent(const char*n)
|
||||
NetEvent::NetEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
scope_ = 0;
|
||||
@@ -51,7 +51,7 @@ NetEvent::~NetEvent()
|
||||
/* name_ is lex_strings. */
|
||||
}
|
||||
|
||||
const char* NetEvent::name() const
|
||||
perm_string NetEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ const char* NetEvent::name() const
|
||||
string NetEvent::full_name() const
|
||||
{
|
||||
assert(scope_);
|
||||
return scope_->name() + "." + name_;
|
||||
return scope_->name() + "." + string(name_);
|
||||
}
|
||||
|
||||
const NetScope* NetEvent::scope() const
|
||||
@@ -201,7 +201,7 @@ NexusSet* NetEvent::nex_async_()
|
||||
if (trig_ != 0)
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
NexusSet*tmp = new NexusSet;
|
||||
for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) {
|
||||
if (cur->edge() != NetEvProbe::ANYEDGE) {
|
||||
@@ -245,13 +245,13 @@ const NetEvent* NetEvTrig::event() const
|
||||
return event_;
|
||||
}
|
||||
|
||||
NetEvProbe::NetEvProbe(NetScope*s, const string&n, NetEvent*tgt,
|
||||
NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt,
|
||||
edge_t t, unsigned p)
|
||||
: NetNode(s, lex_strings.add(n.c_str()), p), event_(tgt), edge_(t)
|
||||
: NetNode(s, n, p), event_(tgt), edge_(t)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < p ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("P", idx);
|
||||
pin(idx).set_name(perm_string::literal("P"), idx);
|
||||
}
|
||||
|
||||
enext_ = event_->probes_;
|
||||
@@ -449,6 +449,15 @@ NetProc* NetEvWait::statement()
|
||||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.26 2004/10/04 01:10:54 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.25 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.24 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.23 2003/04/22 04:48:29 steve
|
||||
* Support event names as expressions elements.
|
||||
*
|
||||
|
||||
+11
-5
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_expr.cc,v 1.21 2003/08/28 04:11:19 steve Exp $"
|
||||
#ident "$Id: net_expr.cc,v 1.23 2004/10/04 01:10:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -32,7 +32,7 @@ NetExpr::TYPE NetExpr::expr_type() const
|
||||
|
||||
/*
|
||||
* Create an add/sub node from the two operands. Make a best guess of
|
||||
* the
|
||||
* the
|
||||
*/
|
||||
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
||||
: NetEBinary(op, l, r)
|
||||
@@ -377,7 +377,7 @@ NetExpr::TYPE NetECReal::expr_type() const
|
||||
return ET_REAL;
|
||||
}
|
||||
|
||||
NetECRealParam::NetECRealParam(NetScope*s, const char*n, const verireal&v)
|
||||
NetECRealParam::NetECRealParam(NetScope*s, perm_string n, const verireal&v)
|
||||
: NetECReal(v), scope_(s), name_(n)
|
||||
{
|
||||
}
|
||||
@@ -386,7 +386,7 @@ NetECRealParam::~NetECRealParam()
|
||||
{
|
||||
}
|
||||
|
||||
const char* NetECRealParam::name() const
|
||||
perm_string NetECRealParam::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
@@ -402,7 +402,7 @@ NetEParam::NetEParam()
|
||||
{
|
||||
}
|
||||
|
||||
NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
|
||||
NetEParam::NetEParam(Design*d, NetScope*s, perm_string n)
|
||||
: des_(d), scope_(s), name_(n)
|
||||
{
|
||||
}
|
||||
@@ -516,6 +516,12 @@ NetExpr::TYPE NetESFunc::expr_type() const
|
||||
|
||||
/*
|
||||
* $Log: net_expr.cc,v $
|
||||
* Revision 1.23 2004/10/04 01:10:54 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.22 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.21 2003/08/28 04:11:19 steve
|
||||
* Spelling patch.
|
||||
*
|
||||
|
||||
+11
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@picturel.com)
|
||||
* Copyright (c) 2000-2004 Stephen Williams (steve@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_force.cc,v 1.11 2003/03/06 00:28:41 steve Exp $"
|
||||
#ident "$Id: net_force.cc,v 1.12 2004/02/18 17:11:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -45,13 +45,13 @@
|
||||
* output pins to connect to the netlist? But that would cause the
|
||||
* link ring to grow, and that is not quite correct either. Hmm...
|
||||
*/
|
||||
NetCAssign::NetCAssign(NetScope*s, const string&n, NetNet*l)
|
||||
: NetNode(s, lex_strings.add(n.c_str()), l->pin_count()), lval_(l)
|
||||
NetCAssign::NetCAssign(NetScope*s, perm_string n, NetNet*l)
|
||||
: NetNode(s, n, l->pin_count()), lval_(l)
|
||||
{
|
||||
lval_->incr_eref();
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("I", idx);
|
||||
pin(idx).set_name(perm_string::literal("I"), idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,14 +87,14 @@ const NetNet*NetDeassign::lval() const
|
||||
return lval_;
|
||||
}
|
||||
|
||||
NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
|
||||
: NetNode(s, lex_strings.add(n.c_str()), l->pin_count()), lval_(l)
|
||||
NetForce::NetForce(NetScope*s, perm_string n, NetNet*l)
|
||||
: NetNode(s, n, l->pin_count()), lval_(l)
|
||||
{
|
||||
lval_->incr_eref();
|
||||
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("I", idx);
|
||||
pin(idx).set_name(perm_string::literal("I"), idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,9 @@ const NetNet*NetRelease::lval() const
|
||||
|
||||
/*
|
||||
* $Log: net_force.cc,v $
|
||||
* Revision 1.12 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.11 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
|
||||
+34
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: net_func.cc,v 1.4 2003/03/06 00:28:41 steve Exp $"
|
||||
#ident "$Id: net_func.cc,v 1.6 2004/05/31 23:34:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -28,15 +28,17 @@
|
||||
|
||||
static unsigned count_def_pins(const NetFuncDef*def)
|
||||
{
|
||||
unsigned sum = 0;
|
||||
assert(def->return_sig());
|
||||
|
||||
unsigned sum = def->return_sig()->pin_count();
|
||||
for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1)
|
||||
sum += def->port(idx)->pin_count();
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
NetUserFunc::NetUserFunc(NetScope*s, const char*n, NetScope*d)
|
||||
: NetNode(s, lex_strings.add(n), count_def_pins(d->func_def())),
|
||||
NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
|
||||
: NetNode(s, n, count_def_pins(d->func_def())),
|
||||
def_(d)
|
||||
{
|
||||
NetFuncDef*def = def_->func_def();
|
||||
@@ -50,7 +52,7 @@ NetUserFunc::NetUserFunc(NetScope*s, const char*n, NetScope*d)
|
||||
unsigned pin_base = port_wid;
|
||||
for (unsigned idx = 1 ; idx < port_count() ; idx += 1) {
|
||||
|
||||
const NetNet*port_sig = def->port(idx);
|
||||
const NetNet*port_sig = def->port(idx-1);
|
||||
unsigned bits = port_width(idx);
|
||||
for (unsigned bit = 0; bit < bits; bit += 1) {
|
||||
pin(pin_base+bit).set_dir(Link::INPUT);
|
||||
@@ -69,13 +71,21 @@ NetUserFunc::~NetUserFunc()
|
||||
|
||||
unsigned NetUserFunc::port_count() const
|
||||
{
|
||||
return def_->func_def()->port_count();
|
||||
return def_->func_def()->port_count() + 1;
|
||||
}
|
||||
|
||||
unsigned NetUserFunc::port_width(unsigned port) const
|
||||
{
|
||||
NetFuncDef*def = def_->func_def();
|
||||
|
||||
/* Port 0 is the return port. */
|
||||
if (port == 0) {
|
||||
const NetNet*sig = def->return_sig();
|
||||
assert(sig);
|
||||
return sig->pin_count();
|
||||
}
|
||||
|
||||
port -= 1;
|
||||
assert(port < def->port_count());
|
||||
const NetNet*port_sig = def->port(port);
|
||||
|
||||
@@ -88,6 +98,13 @@ Link& NetUserFunc::port_pin(unsigned port, unsigned idx)
|
||||
unsigned pin_base = 0;
|
||||
const NetNet*port_sig;
|
||||
|
||||
if (port == 0)
|
||||
return pin(idx);
|
||||
|
||||
port_sig = def->return_sig();
|
||||
pin_base += port_sig->pin_count();
|
||||
port -= 1;
|
||||
|
||||
assert(port < def->port_count());
|
||||
|
||||
for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) {
|
||||
@@ -133,10 +150,10 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((parms_count+1) != dscope->func_def()->port_count()) {
|
||||
if (parms_count != dscope->func_def()->port_count()) {
|
||||
cerr << get_line() << ": error: Function " << dscope->name()
|
||||
<< " expects " << (dscope->func_def()->port_count()-1)
|
||||
<< " parameters, you passed " << parms_count << "."
|
||||
<< " arguments, you passed " << parms_count << "."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
@@ -147,6 +164,14 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
|
||||
|
||||
/*
|
||||
* $Log: net_func.cc,v $
|
||||
* Revision 1.6 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.5 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.4 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user