Compare commits

...
95 Commits
Author SHA1 Message Date
steve 84de8f2b93 Add fpga.tgt to the file list. 2002-02-04 01:31:02 +00:00
steve 08dac488c1 Release 0.6 updates. 2002-02-04 00:48:30 +00:00
steve f2cff31b6e Clean up warnings. 2002-02-04 00:41:34 +00:00
steve 7c3f5c9fae Support print of version number. 2002-02-03 07:05:36 +00:00
steve aa16e82102 Fix parameter bit select check for magic constants. 2002-02-03 05:53:00 +00:00
steve ddd3566d50 Add CVS tokens. 2002-02-03 05:51:31 +00:00
steve ec82af0c74 Use Larrys bits-to-decimal-string code. 2002-02-03 01:01:51 +00:00
steve 78bb3d6f09 Comments about xor evaluation. 2002-02-03 00:06:28 +00:00
steve 54dab22042 event find_similar should not find self. 2002-02-02 06:13:38 +00:00
steve 9756cb6382 Propagate sign in unary minus. 2002-02-01 05:09:14 +00:00
steve 9fa0f95003 Full support for $readmem ranges (Tom Verbeure) 2002-01-31 04:28:17 +00:00
steve a624021a2e Detect duplicate port declarations. 2002-01-31 04:10:15 +00:00
steve 928df5caf7 include config.h to eliminate warnings. 2002-01-29 22:36:31 +00:00
steve 5796524f06 Add ne_expr.cc 2002-01-28 01:39:45 +00:00
steve b761a105b3 release candidate 0.6 2002-01-28 01:33:54 +00:00
steve 364ffc9024 Add support for bit select of parameters.
This leads to a NetESelect node and the
 vvp code generator to support that.
2002-01-28 00:52:41 +00:00
steve 712080f7e0 Detect scalar/vector declarion mismatch. 2002-01-26 05:28:28 +00:00
steve b906f4c0a1 Handle x in l-value of set/x 2002-01-26 02:08:07 +00:00
steve d48bb4d744 Tell check target where to find system.vpi. 2002-01-25 03:25:16 +00:00
steve d67ad166cd Support display of strings with umber formats. (Tom Verbeure) 2002-01-25 03:24:19 +00:00
steve 4e286ea86b Add the vpiLeft.. and vpiRightRange constants 2002-01-24 04:19:39 +00:00
steve a9be4e009f Spelling in comment. 2002-01-24 04:17:46 +00:00
steve 2f05d4b227 bison 1.31 doesnot include stdio.h 2002-01-24 03:57:45 +00:00
steve 0b68639f7d elaborate deassign lval as done for assign. 2002-01-23 05:56:22 +00:00
steve 5f09e01a44 No implicit declaration in assign l-values. 2002-01-23 05:23:17 +00:00
steve 6a98764b3b Load modules with RTLD_LAZY 2002-01-23 04:54:37 +00:00
steve 853c1f4387 Detect incorrect function ports. 2002-01-23 03:35:17 +00:00
steve b99c5aa394 Update for 0.6 release 2002-01-23 02:43:14 +00:00
steve 349be0f169 Precalculate constant results of memory index expressions. 2002-01-22 01:40:04 +00:00
steve 4f28f6a770 Better calcuation of dec string width (Larry Doolittle) 2002-01-22 00:18:10 +00:00
steve fcf64c0c38 More space efficient use of constant strings (Larry Doolittle) 2002-01-22 00:06:56 +00:00
steve da8d59757e return calculated oval from UDP (Stephan Boettcher) 2002-01-20 23:27:51 +00:00
steve a02cfe0f1b Evaluate case guards, if possible. 2002-01-19 20:09:56 +00:00
steve f3255121a2 Spelling fixes. 2002-01-19 19:22:39 +00:00
steve 608555ce7e Pass back target errors processing conditionals. 2002-01-19 19:02:08 +00:00
steve ec8b6e126e Default widths pad out as per the standard,
add $displayb/o/h et al., and some better
 error messages for incorrect formats.
2002-01-15 03:23:34 +00:00
steve a697157257 Support DesSTrVal for binary constants. 2002-01-15 03:21:18 +00:00
steve ec070ee65b Support vpiSize and vpiSigned for time objects. 2002-01-15 03:06:29 +00:00
steve 02f5ccd5d9 Handle constants with drive strength z 2002-01-12 17:49:41 +00:00
steve 361d4f2147 Drive strengths for continuous assignments. 2002-01-12 04:03:39 +00:00
steve c09a148cd9 Make BUFZ device strengths available. 2002-01-12 04:03:09 +00:00
steve b274dada85 Support the BUFZ logic device. 2002-01-12 04:02:16 +00:00
steve c6a937e2e7 The stime system function is 32bits. 2002-01-11 05:25:45 +00:00
steve 5840368f2d Handle certain special cases of stime. 2002-01-11 05:23:05 +00:00
steve dee52dd2d0 Magic stime object support. 2002-01-11 05:21:47 +00:00
steve a0e3b3386d Add the stime system function. 2002-01-11 05:20:59 +00:00
steve 6535b48c1c Add the %c format, and some warning messages. 2002-01-11 04:48:01 +00:00
steve 4d3611c5f1 odd width thread vectors as strings. 2002-01-10 01:54:04 +00:00
steve 77c4c88a4c String prints of non-round vectors (PR378) 2002-01-09 03:29:12 +00:00
steve 4291866b9f Add vpi_get_vlog_info support. 2002-01-09 03:15:23 +00:00
steve 8aef782411 Make lexor_keyword.cc for distributions. 2002-01-07 04:59:21 +00:00
steve 0aa033ddf3 Support scope for functors. (Stephan Boettcher) 2002-01-06 17:50:50 +00:00
steve edba542c7a Feedback output, not propagated output. (Stephan Boettcher) 2002-01-06 17:35:01 +00:00
steve 0e5289b022 Print a useful message for failed include file. 2002-01-06 04:51:31 +00:00
steve 6be3be0f16 Constant values have drive strengths. 2002-01-06 03:15:43 +00:00
steve 03d188fc52 Support weak functor inputs. 2002-01-06 03:15:13 +00:00
steve 6e1e658922 VPI access to root module scopes. 2002-01-06 00:48:39 +00:00
steve a87575a76e make check uses vvp instead of vvm. 2002-01-05 04:36:43 +00:00
steve 336624c7b9 include malloc.h only when available. 2002-01-05 04:36:06 +00:00
steve 71660fbaa5 Implement vpi_mcd_printf. 2002-01-04 02:26:36 +00:00
steve dd79885f6d Add structural modulus support down to vvp. 2002-01-03 04:19:01 +00:00
steve 51ffeb7c06 Use my own cfltype to defend against bison 1.30. 2002-01-02 02:39:34 +00:00
steve 912749342c Parse combinational event delay. 2001-12-31 05:23:13 +00:00
steve 4bb91c4f98 Elaborate multiply nets with constant operands ad NetConst. 2001-12-31 04:23:59 +00:00
steve 400580179f Get sense of 1-bit == operator right. 2001-12-31 01:56:08 +00:00
steve c9d6b5431d Remove test print 2001-12-31 00:39:20 +00:00
steve 51db00fb44 Support $signed cast of expressions. 2001-12-31 00:08:14 +00:00
steve e20acfc9f9 Include s indicator in dump of signed numbers. 2001-12-31 00:02:33 +00:00
steve a3fe753826 Account for negatives in cmp/s 2001-12-31 00:01:16 +00:00
steve 03aebd7525 Support elaborate_net for PEString objects. 2001-12-30 21:32:03 +00:00
steve fd5c0cfa28 Support vpiStringVal in vhtread vectors. 2001-12-30 21:31:38 +00:00
steve 357a0ff23e Detect bison and flex in configure.in 2001-12-30 17:20:33 +00:00
steve 1a22f37d92 Synthesize reduction logic. 2001-12-30 17:06:52 +00:00
steve a5890b914f Properly handle empty target in positionla parameter override. 2001-12-30 04:47:57 +00:00
steve b397b10104 Evaluate constant unary minus. 2001-12-30 00:39:25 +00:00
steve 5de8e0555c push events through event/or lists. 2001-12-29 23:59:06 +00:00
steve 91b01cd67e constant eval of arithmetic with x and z. 2001-12-29 22:10:10 +00:00
steve 9c6b17c887 Allow escaped $ in identifiers. 2001-12-29 20:41:30 +00:00
steve 000d187c94 Do not delete delay expressions of UDP instances. 2001-12-29 20:19:31 +00:00
steve 989e9d4d94 Newline can terminate escaped names. 2001-12-29 19:00:13 +00:00
steve 40ef704cc3 Evaluate constant right shifts. 2001-12-29 00:43:55 +00:00
steve 7c9fe0c173 clarify bufif output strenghts. 2001-12-19 23:43:03 +00:00
steve dddbeb957a Comments about MUX synthesis. 2001-12-18 05:34:02 +00:00
steve fd0cb30a4d Improved functor debug dumps. 2001-12-18 05:32:11 +00:00
steve 125c631091 Remove result length restrictions for vpi_get_value. 2001-12-18 05:31:54 +00:00
steve 443dc7853f Include config.h for namespace declaration. 2001-12-18 04:52:45 +00:00
steve a5400d7212 Support all 3 TRI net types. 2001-12-15 02:13:33 +00:00
steve da09d4c6e6 The IVL_SIT_WIRE type does not exist, it is a
synonym for IVL_SIT_TRI.
2001-12-15 02:13:17 +00:00
steve ace6b0a767 Give tri0 and tri1 their proper strengths. 2001-12-15 02:11:51 +00:00
steve 7d494fd3d5 Support tri0 and tri1 resolvers. 2001-12-15 01:54:38 +00:00
steve cd1524e6ca Generate notif functors. 2001-12-14 06:03:34 +00:00
steve a0526cdd32 Arrange bufif to support notif as well. 2001-12-14 06:03:17 +00:00
steve 4dd5f97a96 Parse and handle drive strengths of gates to vvp. 2001-12-14 02:05:13 +00:00
steve 1ca6fe5519 Support strength syntax on functors. 2001-12-14 02:04:49 +00:00
steve 6b2c604124 Better variable names for functor chunks. 2001-12-14 01:59:28 +00:00
105 changed files with 3786 additions and 967 deletions
+11 -1
View File
@@ -17,13 +17,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: HName.cc,v 1.3 2002/01/05 04:36:06 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
# include <iostream>
# include <string.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
hname_t::hname_t()
{
@@ -249,6 +253,12 @@ ostream& operator<< (ostream&out, const hname_t&that)
/*
* $Log: HName.cc,v $
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+16 -11
View File
@@ -16,12 +16,16 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.109 2001/12/06 02:55:24 steve Exp $"
#ident "$Id: Makefile.in,v 1.114 2002/02/03 07:05:36 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.5
# This version string is only used in the version message printed
# 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.6
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -46,6 +50,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
@@ -66,7 +72,7 @@ all: ivl@EXEEXT@ libvpi.a
cd vvm ; $(MAKE) all
cd vpi ; $(MAKE) all
cd ivlpp ; $(MAKE) all
cd driver ; $(MAKE) all
cd driver ; $(MAKE) VERSION=$(VERSION) all
cd tgt-verilog ; $(MAKE) all
cd tgt-stub ; $(MAKE) all
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
@@ -83,9 +89,8 @@ endif
# sure the basics were compiled properly.
check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
driver/iverilog -Ccheck.conf -ocheck -tvvm-check -B./ivlpp examples/hello.vl
$(CXX) -o check $(rdynamic) -fno-exceptions -I$(srcdir) -I$(srcdir)/vvm -I$(srcdir)/vpip -Lvvm -Lvpip check.cc -lvvm -lvpip $(dllib)
./check | grep 'Hello, World'
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
clean:
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a
@@ -116,8 +121,8 @@ elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_rconst.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o mangle.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
net_scope.o net_udp.o pad_to_width.o \
net_design.o net_event.o net_expr.o net_force.o net_link.o net_modulo.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \
verinum.o verireal.o target.o targets.o \
@@ -170,14 +175,14 @@ lexor.o: lexor.cc parse.h
parse.o: parse.cc
parse.h parse.cc: $(srcdir)/parse.y
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc
+13 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.cc,v 1.7 2001/11/22 06:20:59 steve Exp $"
#ident "$Id: PDelays.cc,v 1.8 2001/12/29 20:19:31 steve Exp $"
#endif
# include "config.h"
@@ -30,14 +30,17 @@
PDelays::PDelays()
{
delete_flag_ = true;
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delay_[idx] = 0;
}
PDelays::~PDelays()
{
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delete delay_[idx];
if (delete_flag_) {
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delete delay_[idx];
}
}
void PDelays::set_delay(PExpr*del)
@@ -45,15 +48,18 @@ void PDelays::set_delay(PExpr*del)
assert(del);
assert(delay_[0] == 0);
delay_[0] = del;
delete_flag_ = true;
}
void PDelays::set_delays(const svector<PExpr*>*del)
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
{
assert(del);
assert(del->count() <= 3);
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
delay_[idx] = (*del)[idx];
delete_flag_ = df;
}
static unsigned long calculate_val(Design*des, const NetScope*scope,
@@ -125,6 +131,9 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
/*
* $Log: PDelays.cc,v $
* Revision 1.8 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.7 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
+9 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.h,v 1.4 2001/11/22 06:20:59 steve Exp $"
#ident "$Id: PDelays.h,v 1.5 2001/12/29 20:19:31 steve Exp $"
#endif
# include "svector.h"
@@ -45,8 +45,11 @@ class PDelays {
PDelays();
~PDelays();
/* Set the delay expressions. If the delete_flag is true, then
this object takes ownership of the expressions, and will
delete it in the destructor. */
void set_delay(PExpr*);
void set_delays(const svector<PExpr*>*del);
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
@@ -57,6 +60,7 @@ class PDelays {
private:
PExpr* delay_[3];
bool delete_flag_;
private: // not implemented
PDelays(const PDelays&);
@@ -67,6 +71,9 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
+6 -14
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: PExpr.cc,v 1.29 2001/12/30 21:32:03 steve Exp $"
#endif
# include "config.h"
@@ -46,18 +46,6 @@ bool PExpr::is_constant(Module*) const
return false;
}
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
unsigned long,
unsigned long,
unsigned long,
Link::strength_t,
Link::strength_t) const
{
cerr << get_line() << ": error: Unable to elaborate `"
<< *this << "' as gates." << endl;
return 0;
}
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_line() << ": error: expression not valid in assign l-value: "
@@ -216,13 +204,14 @@ bool PENumber::is_constant(Module*) const
return true;
}
PEString::PEString(const string&s)
PEString::PEString(char*s)
: text_(s)
{
}
PEString::~PEString()
{
delete[]text_;
}
string PEString::value() const
@@ -267,6 +256,9 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.29 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.28 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+20 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.53 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: PExpr.h,v 1.54 2001/12/30 21:32:03 steve Exp $"
#endif
# include <string>
@@ -285,21 +285,35 @@ class PENumber : public PExpr {
verinum*const value_;
};
/*
* This represents a string constant in an expression.
*
* The s parameter to the PEString constructor is a C string that this
* class instance will take for its own. The caller should not delete
* the string, the destructor will do it.
*/
class PEString : public PExpr {
public:
explicit PEString(const string&s);
explicit PEString(char*s);
~PEString();
string value() const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
private:
const string text_;
char*text_;
};
class PEUnary : public PExpr {
@@ -449,6 +463,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.54 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.53 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+5 -9
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.cc,v 1.7 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: PWire.cc,v 1.8 2002/01/26 05:28:28 steve Exp $"
#endif
# include "config.h"
@@ -39,14 +39,7 @@ NetNet::Type PWire::get_wire_type() const
{
return type_;
}
#if 0
string PWire::name() const
{
string name = hname_[0];
for (unsigned idx = 1 ; hname_[idx] ; idx += 1)
name = name + "." + hname_[idx];
}
#endif
const hname_t& PWire::path() const
{
return hname_;
@@ -127,6 +120,9 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
/*
* $Log: PWire.cc,v $
* Revision 1.8 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.7 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+21 -15
View File
@@ -13,13 +13,13 @@ 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 written in
C++ called VVM, another faster simulator called VVP and an XNF (Xilinx
Netlist Format) generator. See "vvm.txt" and "xnf.txt" for further
details on these back-end processors. In the future, backends are
expected for EDIF/LPM, structural Verilog, VHDL, etc.
C++ called VVM, another faster simulator called VVP, an XNF (Xilinx
Netlist Format) generator and an EDIF fpga netlist generator. In the
future, backends are expected for EDIF/LPM, structural Verilog, VHDL,
etc.
For instructions on how to run Icarus Verilog, see the ``iverilog''
man page.
For instructions on how to run Icarus Verilog,
see the ``iverilog'' man page.
2.0 Building/Installing Icarus Verilog From Source
@@ -30,6 +30,8 @@ system and C/C++ compilation should be able to build the source
distribution with little effort. Some actual programming skills are
not required, but helpful in case of problems.
If you are building for Windows, see the mingw.txt file.
2.1 Compile Time Prerequisites
You need the following software to compile Icarus Verilog from source
@@ -73,7 +75,7 @@ configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libaries are installed or not.
libraries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
@@ -81,8 +83,9 @@ configure script that modify its behavior:
/usr/local/share/ivl, etc.
I recommend that if you are configuring for precompiled
binaries, use --prefix=/usr. On Solaris systems, it is
common to use --prefix=/opt.
binaries, use --prefix=/usr. On Solaris systems, it is
common to use --prefix=/opt. You can configure for a non-root
install with --prefix=$HOME.
2.3 (Optional) Testing
@@ -91,7 +94,7 @@ To run a simple test before installation, execute
make check
The commands printed by this run might help you in running Icarus
Verilog on your own verilog sources before the package is installed
Verilog on your own Verilog sources before the package is installed
by root.
2.4 Installation
@@ -127,7 +130,7 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
3.2 Parse
The verilog compiler starts by parsing the verilog source file. The
The Verilog compiler starts by parsing the Verilog source file. The
output of the parse in a list of Module objects in PFORM. The pform
(see pform.h) is mostly a direct reflection of the compilation
step. There may be dangling references, and it is not yet clear which
@@ -186,7 +189,7 @@ some useful transformations would be,
- eliminate null effect circuitry,
- combinational reduction
- Constant propagation
- constant propagation
The actual functions performed are specified on the ivl command line by
the -F flags (See below).
@@ -206,7 +209,7 @@ command line.
3.6 ATTRIBUTES
The parser accepts as an extension to Verilog the $attribute module
The parser accepts, as an extension to Verilog, the $attribute module
item. The syntax of the $attribute item is:
$attribute (<identifier>, <key>, <value>);
@@ -275,7 +278,7 @@ Usage: ivl <options>... file
This list can also be set with -fVPI_MODULE_LIST=<list> which
sets the list completely. Then, -m after this will append
module names to the list sp specified. The default list
module names to the list specified. The default list
includes "system".
-N <file>
@@ -374,7 +377,7 @@ by the compiler. See the iverilog(1) man page.
Icarus Verilog is in development - as such it still only supports a
(growing) subset of Verilog. Below is a description of some of the
currently unsupported verilog features. This list is not exhaustive,
currently unsupported Verilog features. This list is not exhaustive,
and does not account for errors in the compiler. See the Icarus
Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported
@@ -404,6 +407,8 @@ constructs.
- trireg is not supported. tri0 and tri1 are supported.
- force to nets are not supported. Force to variables, and
assign/deassign, are supported.
6.0 CREDITS
@@ -429,6 +434,7 @@ Verilog guidance, and especially testing from many people, including
Stuart Sutherland <[email protected]>
Stephen Tell <[email protected]>
Stefan Theide <[email protected]>
Tom Verbeure
Steve Wilson <[email protected]>
and others. Testers in particular include a larger community of people
+3
View File
@@ -14,3 +14,6 @@ do
echo "Autoconf in $dir..."
( cd $dir ; autoconf )
done
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
+3
View File
@@ -4,3 +4,6 @@
[-tvvm-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
[-tvvp-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
+16
View File
@@ -14,6 +14,22 @@ then
exit 1
fi
AC_CHECK_PROGS(LEX,flex,none)
if test "$LEX" = "none"
then
echo "*** Error: No suitable flex found. ***"
echo " Please install the 'flex' package."
exit 1
fi
AC_CHECK_PROGS(YACC,bison,none)
if test "$YACC" = "none"
then
echo "*** Error: No suitable bison found. ***"
echo " Please install the 'bison' package."
exit 1
fi
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
+14 -6
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cprop.cc,v 1.30 2001/10/28 01:14:53 steve Exp $"
#ident "$Id: cprop.cc,v 1.32 2002/02/03 00:06:28 steve Exp $"
#endif
# include "config.h"
@@ -217,7 +217,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XOR);
NetLogic::XNOR);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
@@ -583,7 +583,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an XOR gate. */
on the output of an XOR gate. The eliminate works
by unlinking the current input and relinking the
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
idx += 1;
@@ -651,7 +654,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
/* If all the inputs were eliminated, then replace
the gate with a constant 0 and I am done. */
the gate with a constant value and I am done. */
if (top == 1) {
verinum::V out = obj->type()==NetLogic::XNOR
? verinum::V1
@@ -887,7 +890,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
return;
// Look for signals that have NetESignal nodes attached to
// them. If I find any, this this constant is used by a
// them. If I find any, then this constant is used by a
// behavioral expression somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
Nexus*nex = obj->pin(idx).nexus();
@@ -920,7 +923,6 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
}
}
// Done. Delete me.
delete obj;
}
@@ -942,6 +944,12 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.32 2002/02/03 00:06:28 steve
* Comments about xor evaluation.
*
* Revision 1.31 2001/12/31 01:56:08 steve
* Get sense of 1-bit == operator right.
*
* Revision 1.30 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
+6 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: design_dump.cc,v 1.121 2001/12/31 00:03:05 steve Exp $"
#endif
# include "config.h"
@@ -884,6 +884,8 @@ void NetESFunc::dump(ostream&o) const
void NetESignal::dump(ostream&o) const
{
if (has_sign())
o << "+";
o << name() << "[" << msi_<<":"<<lsi_ << "]";
}
@@ -970,6 +972,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.121 2001/12/31 00:03:05 steve
* Include s indicator in dump of signed numbers.
*
* Revision 1.120 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+3 -3
View File
@@ -18,12 +18,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.10 2001/11/17 17:57:58 steve Exp $"
#ident "$Id: Makefile.in,v 1.11 2002/02/03 07:05:36 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
VERSION = 0.6
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -46,7 +46,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
+2 -1
View File
@@ -18,11 +18,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cfparse.y,v 1.5 2001/12/08 04:13:07 steve Exp $"
#ident "$Id: cfparse.y,v 1.6 2002/01/02 02:39:34 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
# include <ctype.h>
/*
+18 -1
View File
@@ -20,12 +20,29 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: cfparse_misc.h,v 1.2 2001/11/12 18:47:32 steve Exp $"
#ident "$Id: cfparse_misc.h,v 1.3 2002/01/02 02:39:34 steve Exp $"
#endif
/*
* The vlltype supports the passing of detailed source file location
* information between the lexical analyzer and the parser. Defining
* YYLTYPE compels the lexor to use this type and not something other.
*/
struct cfltype {
unsigned first_line;
unsigned first_column;
unsigned last_line;
unsigned last_column;
const char*text;
};
# define YYLTYPE struct cfltype
extern YYLTYPE yylloc;
/*
* $Log: cfparse_misc.h,v $
* Revision 1.3 2002/01/02 02:39:34 steve
* Use my own cfltype to defend against bison 1.30.
*
* Revision 1.2 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
+7 -3
View File
@@ -1,10 +1,10 @@
.TH iverilog 1 "$Date: 2001/12/08 04:13:07 $" Version "$Date: 2001/12/08 04:13:07 $"
.TH iverilog 1 "$Date: 2002/02/03 07:05:37 $" Version "$Date: 2002/02/03 07:05:37 $"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
[-ESVv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
@@ -111,7 +111,11 @@ Use this switch to specify the target output format. See the
.B -v
Turn on verbose messages. This will print the command lines that are
executed to perform the actual compilation, along with version
information from the various components.
information from the various components, as well as the version of the
product as a whole.
.TP 8
.B -V
Print the version of the compiler, and exit.
.TP 8
.B -W\fIclass\fP
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
+20 -3
View File
@@ -16,12 +16,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: main.c,v 1.31 2001/11/21 02:20:34 steve Exp $"
#ident "$Id: main.c,v 1.32 2002/02/03 07:05:37 steve Exp $"
# include "config.h"
const char HELP[] =
"Usage: iverilog [-ESv] [-B base] [-C path] [-c cmdfile]\n"
"Usage: iverilog [-ESvV] [-B base] [-C path] [-c cmdfile]\n"
" [-D macro[=defn]] [-I includedir] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
@@ -347,6 +348,7 @@ int main(int argc, char **argv)
char*cmd;
unsigned ncmd;
int e_flag = 0;
int version_flag = 0;
int opt, idx;
char*cp;
@@ -392,7 +394,7 @@ int main(int argc, char **argv)
source_file = fopen(source_path, "w");
assert(source_file);
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) {
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vVW:y:")) != EOF) {
switch (opt) {
case 'B':
@@ -493,6 +495,9 @@ int main(int argc, char **argv)
case 'v':
verbose_flag = 1;
break;
case 'V':
version_flag = 1;
break;
case 'W':
process_warning_switch(optarg);
break;
@@ -508,6 +513,15 @@ int main(int argc, char **argv)
}
}
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION "\n");
printf("Copyright 1998-2002 Stephen Williams\n");
printf("$Name: $\n");
if (version_flag)
return 0;
}
if (command_filename) {
int rc;
@@ -624,6 +638,9 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.32 2002/02/03 07:05:37 steve
* Support print of version number.
*
* Revision 1.31 2001/11/21 02:20:34 steve
* Pass list of file to ivlpp via temporary file.
*
+12 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: dup_expr.cc,v 1.6 2001/11/19 01:54:14 steve Exp $"
#ident "$Id: dup_expr.cc,v 1.7 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -31,6 +31,12 @@ NetEScope* NetEScope::dup_expr() const
return 0;
}
NetESelect* NetESelect::dup_expr() const
{
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
expr_width());
}
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
@@ -68,6 +74,11 @@ NetEUnary* NetEUnary::dup_expr() const
/*
* $Log: dup_expr.cc,v $
* Revision 1.7 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.6 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
+65 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.46 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.50 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -162,10 +162,32 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
*/
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
{
/* Catch the special case that the system function is the
$signed function. This function is special, in that it does
not lead to executable code but takes the single parameter
and makes it into a signed expression. No bits are changed,
it just changes the interpretation. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope);
sub->cast_signed(true);
return sub;
}
unsigned wid = 32;
if (strcmp(path_.peek_name(0), "$time") == 0)
wid = 64;
if (strcmp(path_.peek_name(0), "$stime") == 0)
wid = 32;
/* How many parameters are there? The Verilog language allows
@@ -369,10 +391,19 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
return new NetEConst(verinum(val));
}
/*
* Elaborate an identifier in an expression. The identifier can be a
* parameter name, a signal name or a memory name. It can also be a
* scope name (Return a NetEScope) but only certain callers can use
* scope names. However, we still support it here.
*
* Function names are not handled here, they are detected by the
* parser and are elaborated by PECallFunction.
*
* The signal name may be escaped, but that affects nothing here.
*/
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
{
assert(path_.peek_name(0)[0] != '$');
assert(scope);
// If the identifier name is a parameter name, then return
@@ -384,6 +415,23 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
else
tmp = new NetEParam(des, scope, path_);
if (msb_ && lsb_) {
cerr << get_line() << ": error: part select of "
<< "parameter " << path_ << " in " << scope->name()
<< " is illegal." << endl;
des->errors += 1;
} else if (msb_) {
/* Handle the case where a parameter has a bit
select attached to it. Generate a NetESelect
object to select the bit as desired. */
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
tmp->set_line(*this);
tmp = stmp;
}
tmp->set_line(*this);
return tmp;
}
@@ -642,6 +690,20 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.50 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.49 2002/01/11 05:25:45 steve
* The stime system function is 32bits.
*
* Revision 1.48 2001/12/31 00:08:14 steve
* Support $signed cast of expressions.
*
* Revision 1.47 2001/12/29 20:41:30 steve
* Allow escaped $ in identifiers.
*
* Revision 1.46 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+118 -12
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_net.cc,v 1.82 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_net.cc,v 1.86 2002/01/23 05:23:17 steve Exp $"
#endif
# include "config.h"
@@ -29,6 +29,18 @@
# include <iostream>
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
unsigned long,
unsigned long,
unsigned long,
Link::strength_t,
Link::strength_t) const
{
cerr << get_line() << ": error: Unable to elaborate `"
<< *this << "' as gates." << endl;
return 0;
}
/*
* Elaborating binary operations generally involves elaborating the
* left and right expressions, then making an output wire and
@@ -642,9 +654,12 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope,
NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
if (rsig == 0) return 0;
unsigned rwidth = lsig->pin_count();
if (rsig->pin_count() > rwidth)
rwidth = rsig->pin_count();
unsigned rwidth = lwidth;
if (rwidth == 0) {
rwidth = lsig->pin_count();
if (rsig->pin_count() > rwidth)
rwidth = rsig->pin_count();
}
NetModulo*mod = new NetModulo(scope, scope->local_hsymbol(), rwidth,
lsig->pin_count(),
rsig->pin_count());
@@ -771,12 +786,45 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
unsigned long fall,
unsigned long decay) const
{
verinum*lnum = left_->eval_const(des, scope);
verinum*rnum = right_->eval_const(des, scope);
/* Detect and handle the special case that both the operands
of the multiply are constant expressions. Evalulate the
value and make this a simple constant. */
if (lnum && rnum) {
verinum prod = *lnum * *rnum;
if (lwidth == 0)
lwidth = prod.len();
verinum res (verinum::V0, lwidth);
for (unsigned idx = 0
; idx < prod.len() && idx < lwidth
; idx += 1) {
res.set(idx, prod.get(idx));
}
NetConst*odev = new NetConst(scope, scope->local_hsymbol(), res);
NetNet*osig = new NetNet(scope, scope->local_hsymbol(),
NetNet::IMPLICIT, lwidth);
for (unsigned idx = 0 ; idx < lwidth ; idx += 1)
connect(odev->pin(idx), osig->pin(idx));
des->add_node(odev);
osig->local_flag(true);
return osig;
}
NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (lsig == 0) return 0;
NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
if (rsig == 0) return 0;
unsigned rwidth = lwidth;
if (rwidth == 0) {
rwidth = lsig->pin_count() + rsig->pin_count();
}
NetMult*mult = new NetMult(scope, scope->local_hsymbol(), rwidth,
lsig->pin_count(),
rsig->pin_count());
@@ -1232,14 +1280,11 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
return 0;
}
/* Fine, create an implicit wire as an l-value. */
sig = new NetNet(scope, path+"."+path_.peek_name(0),
NetNet::IMPLICIT, 1);
if (warn_implicit)
cerr << get_line() << ": warning: implicit "
" definition of wire " << path << "." <<
path_.peek_name(0) << "." << endl;
cerr << get_line() << ": error: Net " << path_
<< " is not defined in this context." << endl;
cerr << get_line() << ": : Do you mean this? wire "
<< path_ << " = <expr>;" << endl;
return 0;
}
assert(sig);
@@ -1539,6 +1584,55 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
return net;
}
/*
* A string is a NetEConst node that is made of the ASCII bits of the
* string instead of the bits of a number. In fact, a string is just
* another numeric notation.
*/
NetNet* PEString::elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const
{
unsigned strbits = strlen(text_) * 8;
NetNet*net;
/* If we are constrained by a l-value size, then just make a
number constant with the correct size and set as many bits
in that constant as make sense. Pad excess with zeros. */
if (lwidth > 0) {
net = new NetNet(scope, scope->local_hsymbol(),
NetNet::IMPLICIT, lwidth);
} else {
net = new NetNet(scope, scope->local_hsymbol(),
NetNet::IMPLICIT, strbits);
}
net->local_flag(true);
/* Make a verinum that is filled with the 0 pad. */
verinum num(verinum::V0, net->pin_count());
unsigned idx;
for (idx = 0 ; idx < num.len() && idx < strbits; idx += 1) {
char byte = text_[strbits/8 - 1 - idx/8];
char mask = 1<<(idx%8);
num.set(idx, (byte & mask)? verinum::V1 : verinum::V0);
}
NetConst*tmp = new NetConst(scope, scope->local_hsymbol(), num);
for (idx = 0 ; idx < net->pin_count() ; idx += 1) {
tmp->pin(idx).drive0(drive0);
tmp->pin(idx).drive1(drive1);
connect(net->pin(idx), tmp->pin(idx));
}
des->add_node(tmp);
return net;
}
/*
* Elaborate the ternary operator in a netlist by creating a LPM_MUX
@@ -1880,6 +1974,18 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* Revision 1.86 2002/01/23 05:23:17 steve
* No implicit declaration in assign l-values.
*
* Revision 1.85 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.84 2001/12/31 04:23:59 steve
* Elaborate multiply nets with constant operands ad NetConst.
*
* Revision 1.83 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.82 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+12 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.13 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -152,6 +152,12 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
return 0;
}
if (msb_ || lsb_ || idx_) {
cerr << get_line() << ": error: Cannot bit/part select "
"bits of parameters." << endl;
des->errors += 1;
}
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res);
delete name;
@@ -218,6 +224,11 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.13 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+19 -8
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_scope.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.13 2001/12/30 04:47:57 steve Exp $"
#endif
# include "config.h"
@@ -256,8 +256,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. This map receives
// those replacements.
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrices or named
// overrides.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
map<string,PExpr*> replace;
@@ -271,12 +273,18 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (overrides_) {
assert(parms_ == 0);
list<string>::const_iterator cur = mod->param_names.begin();
for (unsigned idx = 0
; idx < overrides_->count()
; idx += 1, cur++) {
replace[*cur] = (*overrides_)[idx];
}
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
replace[*cur] = (*overrides_)[idx];
idx += 1;
cur ++;
}
}
// Named parameter overrides carry a name with each override
@@ -459,6 +467,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.13 2001/12/30 04:47:57 steve
* Properly handle empty target in positionla parameter override.
*
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+42 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.18 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.20 2002/01/26 05:28:28 steve Exp $"
#endif
# include "config.h"
@@ -237,6 +237,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
string fname = scope->basename();
assert(scope->type() == NetScope::FUNC);
/* Make sure the function has at least one input port. If it
fails this test, print an error message. Keep going so we
can find more errors. */
if (ports_ == 0) {
cerr << get_line() << ": error: Function " << fname
<< " has no ports." << endl;
cerr << get_line() << ": : Functions must have"
<< " at least one input port." << endl;
des->errors += 1;
}
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
/* Get the reg for the return value. I know the name of the
@@ -379,6 +390,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if (msb_.count()) {
svector<long>mnum (msb_.count());
svector<long>lnum (msb_.count());
/* There may be places where the signal is declared as a
scaler. Count those here, for consistency check
later. */
unsigned count_scalars = 0;
/* There may be multiple declarations of ranges, because
the symbol may have its range declared in i.e. input
@@ -387,6 +402,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
if (msb_[idx] == 0) {
count_scalars += 1;
assert(lsb_[idx] == 0);
mnum[idx] = 0;
lnum[idx] = 0;
continue;
}
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
@@ -417,6 +440,18 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
}
/* Check that the declarations were all scalar or all
vector. It is an error to mix them. Use the
count_scalars to know. */
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
cerr << get_line() << ": error: Signal ``" << hname_
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return;
}
/* Make sure all the values for msb and lsb match by
value. If not, report an error. */
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
@@ -484,6 +519,12 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/*
* $Log: elab_sig.cc,v $
* Revision 1.20 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.19 2002/01/23 03:35:17 steve
* Detect incorrect function ports.
*
* Revision 1.18 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+30 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.236 2001/12/06 05:04:49 steve Exp $"
#ident "$Id: elaborate.cc,v 1.240 2002/01/23 05:56:22 steve Exp $"
#endif
# include "config.h"
@@ -669,11 +669,11 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
unsigned long rise_time = 0, fall_time = 0, decay_time = 0;
if (overrides_) {
PDelays tmp_del;
tmp_del.set_delays(overrides_);
tmp_del.set_delays(overrides_, false);
tmp_del.eval_delays(des, scope, rise_time, fall_time, decay_time);
delete overrides_;
}
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->set_attributes(udp->attributes);
net->rise_time(rise_time);
@@ -1200,6 +1200,10 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetCase*res = new NetCase(type_, expr, icount);
res->set_line(*this);
/* Iterate over all the case items (guard/statement pairs)
elaborating them. If the guard has no expression, then this
is a "default" cause. Otherwise, the guard has one or more
expressions, and each guard is a case. */
unsigned inum = 0;
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
@@ -1227,6 +1231,16 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
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;
}
}
if (cur->stat)
st = cur->stat->elaborate(des, scope);
@@ -1520,7 +1534,7 @@ NetDeassign* PDeassign::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
NetNet*lval = lval_->elaborate_net(des, scope, 0, 0, 0, 0);
NetNet*lval = lval_->elaborate_anet(des, scope);
if (lval == 0)
return 0;
@@ -2394,6 +2408,18 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.240 2002/01/23 05:56:22 steve
* elaborate deassign lval as done for assign.
*
* Revision 1.239 2002/01/19 20:09:56 steve
* Evaluate case guards, if possible.
*
* Revision 1.238 2001/12/31 00:39:20 steve
* Remove test print
*
* Revision 1.237 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.236 2001/12/06 05:04:49 steve
* Forgot to evaluate UDP delays.
*
+23 -7
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.63 2001/10/19 21:53:24 steve Exp $"
#ident "$Id: emit.cc,v 1.65 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -186,8 +186,7 @@ bool NetCAssign::emit_proc(struct target_t*tgt) const
bool NetCondit::emit_proc(struct target_t*tgt) const
{
tgt->proc_condit(this);
return true;
return tgt->proc_condit(this);
}
bool NetDeassign::emit_proc(struct target_t*tgt) const
@@ -263,16 +262,20 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
} while (cur != last_);
}
void NetCondit::emit_recurse_if(struct target_t*tgt) const
bool NetCondit::emit_recurse_if(struct target_t*tgt) const
{
if (if_)
if_->emit_proc(tgt);
return if_->emit_proc(tgt);
else
return true;
}
void NetCondit::emit_recurse_else(struct target_t*tgt) const
bool NetCondit::emit_recurse_else(struct target_t*tgt) const
{
if (else_)
else_->emit_proc(tgt);
return else_->emit_proc(tgt);
else
return true;
}
bool NetEvProbe::emit_node(struct target_t*tgt) const
@@ -431,6 +434,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_scope(this);
}
void NetESelect::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_select(this);
}
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_sfunc(this);
@@ -474,6 +482,14 @@ bool emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.65 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.64 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.63 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
+54 -27
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: eval.cc,v 1.26 2001/12/29 22:10:10 steve Exp $"
#endif
# include "config.h"
@@ -46,46 +46,56 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
switch (op_) {
case '+': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv+rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv+rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '-': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '*': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv * rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv * rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '/': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv / rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv / rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '%': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv % rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv % rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case 'l': {
case 'l': { // left shift (<<)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
res = new verinum(verinum::V0, l->len());
@@ -96,6 +106,17 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
}
break;
}
case 'r': { // right shift (>>)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
res = new verinum(verinum::V0, l->len());
if (rv < res->len()) {
unsigned cnt = res->len() - rv;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
res->set(idx, l->get(idx+rv));
}
break;
}
default:
delete l;
@@ -196,6 +217,12 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
/*
* $Log: eval.cc,v $
* Revision 1.26 2001/12/29 22:10:10 steve
* constant eval of arithmetic with x and z.
*
* Revision 1.25 2001/12/29 00:43:55 steve
* Evaluate constant right shifts.
*
* Revision 1.24 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+72 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_tree.cc,v 1.30 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.33 2002/02/01 05:09:14 steve Exp $"
#endif
# include "config.h"
@@ -758,6 +758,50 @@ NetEConst* NetEConcat::eval_tree()
return res;
}
/*
* There are limits to our ability to evaluate a memory reference
* expression, because the content of a memory is never
* constant. However, the index expression may be precalculated, and
* there are certain index values that do give us constant results.
*/
NetExpr* NetEMemory::eval_tree()
{
/* Attempt to evaluate the index expression to a constant, if
it is not already. */
if (idx_ && !dynamic_cast<NetEConst*>(idx_)) {
NetExpr* tmp = idx_->eval_tree();
if (tmp) {
delete idx_;
idx_ = tmp;
}
}
NetEConst*itmp = dynamic_cast<NetEConst*>(idx_);
if (itmp == 0)
return 0;
verinum ival = itmp->value();
/* If the index expression has any x or z bits, then we know
already that the expression result is a constant x. */
if (! ival.is_defined()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
}
/* If the index expression is outside the range of the memory,
then the result is a constant x. */
unsigned norm_idx = mem_->index_to_address(ival.as_long());
if (norm_idx >= mem_->count()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
}
return 0;
}
NetExpr* NetEParam::eval_tree()
{
if (des_ == 0)
@@ -911,6 +955,24 @@ NetEConst* NetEUnary::eval_tree()
switch (op_) {
case '+':
/* Unary + is a no-op. */
return new NetEConst(val);
case '-': {
if (val.is_defined()) {
verinum tmp (verinum::V0, val.len());
tmp.has_sign(val.has_sign());
val = tmp - val;
} else {
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
val.set(idx, verinum::Vx);
}
return new NetEConst(val);
}
case '~': {
/* Bitwise not is even simpler then logical
@@ -1002,6 +1064,15 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.33 2002/02/01 05:09:14 steve
* Propagate sign in unary minus.
*
* Revision 1.32 2002/01/22 01:40:04 steve
* Precalculate constant results of memory index expressions.
*
* Revision 1.31 2001/12/30 00:39:25 steve
* Evaluate constant unary minus.
*
* Revision 1.30 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+33 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: expr_synth.cc,v 1.29 2001/11/29 01:58:18 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.31 2001/12/30 17:06:52 steve Exp $"
#endif
# include "config.h"
@@ -467,6 +467,26 @@ NetNet* NetEUReduce::synthesize(Design*des)
NetLogic::AND);
break;
case '|':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::OR);
break;
case '^':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XOR);
break;
case 'A':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::NAND);
break;
case 'X':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XNOR);
break;
default:
cerr << get_line() << ": internal error: "
<< "Unable to synthesize " << *this << "." << endl;
@@ -481,7 +501,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
return osig;
}
/*
* Synthesize a ?: operator an a NetMux device. Connect the condition
* expression to the select input, then connect the true and false
* expressions to the B and A inputs. This way, when the select input
* is one, the B input, which is the true expression, is selected.
*/
NetNet* NetETernary::synthesize(Design *des)
{
NetNet*csig = cond_->synthesize(des);
@@ -562,6 +587,12 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.31 2001/12/30 17:06:52 steve
* Synthesize reduction logic.
*
* Revision 1.30 2001/12/18 05:34:02 steve
* Comments about MUX synthesis.
*
* Revision 1.29 2001/11/29 01:58:18 steve
* Handle part selects in l-values of DFF devices.
*
+25 -1
View File
@@ -318,8 +318,32 @@ the right length, and will therefore flag instances u5 and u6 as
errors. The IEEE1364 standard should be more specific one way or the
other.
$Id: ieee1364-notes.txt,v 1.8 2001/08/01 05:17:31 steve Exp $
* UNKNOWN VALUES IN L-VALUE BIT SELECTS
Consider this example:
reg [7:0] vec;
wire [4:0] idx = <expr>;
[...]
vec[idx] = 1;
So long as the value of idx is a valid bit select address, the
behavior of this assignment is obvious. However, there is no explicit
word in the standard as to what happens if the value is out of
range. The standard clearly states the value of an expression when the
bit-select or part select is out of range (the value is x) but does
not address the behavior when the expression is an l-value.
Icarus Verilog will take the position that bit select expressions in
the l-value will select oblivion if it is out of range. That is, if
idx has a value that is not a valid bit select of vec, then the
assignment will have no effect.
$Id: ieee1364-notes.txt,v 1.9 2002/01/26 02:08:07 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
+15 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_target.h,v 1.89 2001/12/06 03:11:00 steve Exp $"
#ident "$Id: ivl_target.h,v 1.92 2002/01/28 00:52:41 steve Exp $"
#endif
#ifdef __cplusplus
@@ -164,6 +164,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_MEMORY,
IVL_EX_NUMBER,
IVL_EX_SCOPE,
IVL_EX_SELECT,
IVL_EX_SFUNC,
IVL_EX_SIGNAL,
IVL_EX_STRING,
@@ -210,6 +211,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_CMP_NE = 11,
IVL_LPM_DIVIDE = 12,
IVL_LPM_FF = 3,
IVL_LPM_MOD = 13,
IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5,
IVL_LPM_SHIFTL = 6,
@@ -258,7 +260,6 @@ typedef enum ivl_signal_type_e {
IVL_SIT_TRIAND,
IVL_SIT_TRIOR,
IVL_SIT_WAND,
IVL_SIT_WIRE,
IVL_SIT_WOR
} ivl_signal_type_t;
@@ -977,6 +978,18 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.92 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.91 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.90 2001/12/15 02:13:17 steve
* The IVL_SIT_WIRE type does not exist, it is a
* synonym for IVL_SIT_TRI.
*
* Revision 1.89 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
+3 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.28 2001/11/29 02:26:25 steve Exp $"
#ident "$Id: lexor.lex,v 1.29 2002/01/06 04:51:31 steve Exp $"
#endif
# include "config.h"
@@ -525,7 +525,8 @@ static void do_include()
}
if (standby->file == 0) {
perror(standby->path);
fprintf(stderr, "%s:%u: Include file %s not found\n",
istack->path, istack->lineno, standby->path);
exit(1);
}
+3 -1
View File
@@ -19,9 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.2 2000/08/20 17:49:05 steve Exp $"
#ident "$Id: parse.y,v 1.3 2002/01/24 03:57:45 steve Exp $"
#endif
# include <stdio.h>
static void yyerror(const char*msg);
%}
+2 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.67 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: lexor.lex,v 1.68 2001/12/29 19:00:13 steve Exp $"
#endif
# include "config.h"
@@ -193,7 +193,7 @@ W [ \t\b\f\r]+
}
\\[^ \t\b\f\r]+ {
\\[^ \t\b\f\r\n]+ {
yylval.text = strdup(yytext+1);
return IDENTIFIER; }
+10 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_event.cc,v 1.16 2001/10/28 01:14:53 steve Exp $"
#ident "$Id: net_event.cc,v 1.17 2002/02/02 06:13:38 steve Exp $"
#endif
# include "config.h"
@@ -171,7 +171,12 @@ NetEvent* NetEvent::find_similar_event()
if (tmp->edge() != cur->edge())
continue;
table[ncand++].ev = tmp->event();
/* Don't include myself in the list of candidates. */
NetEvent*etmp = tmp->event();
if (etmp == this)
continue;
table[ncand++].ev = etmp;
assert(ncand <= max_cand);
}
@@ -451,6 +456,9 @@ NetProc* NetEvWait::statement()
/*
* $Log: net_event.cc,v $
* Revision 1.17 2002/02/02 06:13:38 steve
* event find_similar should not find self.
*
* Revision 1.16 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: net_expr.cc,v 1.2 2002/01/29 22:36:31 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
: expr_(exp), base_(base)
{
expr_width(wid);
}
NetESelect::~NetESelect()
{
delete expr_;
delete base_;
}
const NetExpr*NetESelect::sub_expr() const
{
return expr_;
}
const NetExpr*NetESelect::select() const
{
return base_;
}
bool NetESelect::has_width() const
{
return true;
}
bool NetESelect::set_width(unsigned w)
{
if (expr_width() == 1)
return true;
else
return false;
}
/*
* $Log: net_expr.cc,v $
* Revision 1.2 2002/01/29 22:36:31 steve
* include config.h to eliminate warnings.
*
* Revision 1.1 2002/01/28 01:39:45 steve
* Add ne_expr.cc
*
*/
+7 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_force.cc,v 1.6 2001/11/14 03:28:49 steve Exp $"
#ident "$Id: net_force.cc,v 1.7 2002/01/19 19:02:08 steve Exp $"
#endif
# include "config.h"
@@ -89,6 +89,8 @@ const NetNet*NetDeassign::lval() const
NetForce::NetForce(NetScope*s, const 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);
@@ -97,6 +99,7 @@ NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
NetForce::~NetForce()
{
lval_->decr_eref();
}
const Link& NetForce::lval_pin(unsigned idx) const
@@ -127,6 +130,9 @@ const NetNet*NetRelease::lval() const
/*
* $Log: net_force.cc,v $
* Revision 1.7 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.6 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
+38 -13
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.cc,v 1.178 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: netlist.cc,v 1.181 2002/02/01 05:09:14 steve Exp $"
#endif
# include "config.h"
@@ -1789,7 +1789,7 @@ const NetScope* NetUTask::task() const
}
NetExpr::NetExpr(unsigned w)
: width_(w)
: width_(w), signed_flag_(false)
{
}
@@ -1799,7 +1799,12 @@ NetExpr::~NetExpr()
bool NetExpr::has_sign() const
{
return false;
return signed_flag_;
}
void NetExpr::cast_signed(bool flag)
{
signed_flag_ = flag;
}
bool NetExpr::has_width() const
@@ -2046,6 +2051,7 @@ NetEConcat* NetEConcat::dup_expr() const
NetEConst::NetEConst(const verinum&val)
: NetExpr(val.len()), value_(val)
{
cast_signed(value_.has_sign());
}
NetEConst::~NetEConst()
@@ -2057,11 +2063,6 @@ const verinum& NetEConst::value() const
return value_;
}
bool NetEConst::has_sign() const
{
return value_.has_sign();
}
bool NetEConst::has_width() const
{
return value_.has_len();
@@ -2083,6 +2084,16 @@ NetEMemory::~NetEMemory()
{
}
const string& NetEMemory::name() const
{
return mem_->name();
}
const NetExpr* NetEMemory::index() const
{
return idx_;
}
NetMemory::NetMemory(NetScope*sc, const string&n, long w, long s, long e)
: name_(n), width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc)
{
@@ -2214,6 +2225,7 @@ NetESignal::NetESignal(NetNet*n)
lsi_ = 0;
net_->incr_eref();
set_line(*n);
cast_signed(net_->get_signed());
}
NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
@@ -2224,6 +2236,7 @@ NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
lsi_ = l;
net_->incr_eref();
set_line(*n);
cast_signed(net_->get_signed());
}
NetESignal::~NetESignal()
@@ -2236,11 +2249,6 @@ string NetESignal::name() const
return net_->name();
}
bool NetESignal::has_sign() const
{
return net_->get_signed();
}
unsigned NetESignal::bit_count() const
{
return msi_ - lsi_ + 1;
@@ -2331,6 +2339,14 @@ NetEUnary::NetEUnary(char op, NetExpr*ex)
expr_width(1);
break;
}
switch (op_) {
case '-':
case '+':
cast_signed(ex->has_sign());
break;
default:
;
}
}
NetEUnary::~NetEUnary()
@@ -2407,6 +2423,15 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.181 2002/02/01 05:09:14 steve
* Propagate sign in unary minus.
*
* Revision 1.180 2002/01/22 01:40:04 steve
* Precalculate constant results of memory index expressions.
*
* Revision 1.179 2001/12/31 00:08:14 steve
* Support $signed cast of expressions.
*
* Revision 1.178 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+50 -12
View File
@@ -1,7 +1,7 @@
#ifndef __netlist_H
#define __netlist_H
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: netlist.h,v 1.231 2002/01/28 00:52:41 steve Exp $"
#endif
/*
@@ -847,7 +847,8 @@ class NetExpr : public LineInfo {
// This method returns true if the expression is
// signed. Unsigned expressions return false.
virtual bool has_sign() const;
bool has_sign() const;
void cast_signed(bool flag);
// This returns true if the expression has a definite
// width. This is generally true, but in some cases the
@@ -880,6 +881,7 @@ class NetExpr : public LineInfo {
private:
unsigned width_;
bool signed_flag_;
private: // not implemented
NetExpr(const NetExpr&);
@@ -901,7 +903,6 @@ class NetEConst : public NetExpr {
virtual bool set_width(unsigned w);
virtual bool has_sign() const;
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
@@ -1454,8 +1455,8 @@ class NetCondit : public NetProc {
// Replace the condition expression.
void set_expr(NetExpr*ex);
void emit_recurse_if(struct target_t*) const;
void emit_recurse_else(struct target_t*) const;
bool emit_recurse_if(struct target_t*) const;
bool emit_recurse_else(struct target_t*) const;
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
@@ -2307,6 +2308,32 @@ class NetEParam : public NetExpr {
};
/*
* This expression node supports bit/part selects from general
* expressions. The sub-expression is self-sized, and has bits
* selected from it. The base is the expression that identifies the
* lsb of the expression, and the wid is the width of the part select,
* or 1 for a bit select.
*/
class NetESelect : public NetExpr {
public:
NetESelect(NetExpr*exp, NetExpr*base, unsigned wid);
~NetESelect();
const NetExpr*sub_expr() const;
const NetExpr*select() const;
virtual bool set_width(unsigned w);
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetESelect* dup_expr() const;
private:
NetExpr*expr_;
NetExpr*base_;
};
/*
* This class is a special (and magical) expression node type that
* represents scope names. These can only be found as parameters to
@@ -2466,11 +2493,12 @@ class NetEMemory : public NetExpr {
NetEMemory(NetMemory*mem, NetExpr*idx =0);
virtual ~NetEMemory();
const string& name () const { return mem_->name(); }
const NetExpr* index() const { return idx_; }
const string& name () const;
const NetExpr* index() const;
virtual bool set_width(unsigned);
NetExpr* eval_tree();
virtual NetEMemory*dup_expr() const;
virtual void expr_scan(struct expr_scan_t*) const;
@@ -2501,10 +2529,6 @@ class NetESignal : public NetExpr {
NetESignal(NetNet*n, unsigned msi, unsigned lsi);
~NetESignal();
// a NetESignal expression is signed if the NetNet that it
// refers to is signed.
bool has_sign() const;
string name() const;
virtual bool set_width(unsigned);
@@ -2867,6 +2891,20 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.231 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.230 2002/01/22 01:40:04 steve
* Precalculate constant results of memory index expressions.
*
* Revision 1.229 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.228 2001/12/31 00:08:14 steve
* Support $signed cast of expressions.
*
* Revision 1.227 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+5 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: nodangle.cc,v 1.13 2001/07/27 02:41:55 steve Exp $"
#ident "$Id: nodangle.cc,v 1.14 2002/02/02 06:13:38 steve Exp $"
#endif
# include "config.h"
@@ -42,6 +42,7 @@ class nodangle_f : public functor_t {
void nodangle_f::event(Design*des, NetEvent*ev)
{
if (NetEvent*match = ev->find_similar_event()) {
assert(match != ev);
ev->replace_event(match);
}
@@ -130,6 +131,9 @@ void nodangle(Design*des)
/*
* $Log: nodangle.cc,v $
* Revision 1.14 2002/02/02 06:13:38 steve
* event find_similar should not find self.
*
* Revision 1.13 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
*
+32 -19
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.140 2001/12/07 05:03:13 steve Exp $"
#ident "$Id: parse.y,v 1.145 2002/01/23 03:35:17 steve Exp $"
#endif
# include "config.h"
@@ -31,11 +31,11 @@ extern void lex_start_table();
extern void lex_end_table();
/*
* These are the strengths to use for net declaration
* assignments. They are stored here so that scope that contains the
* net_decl_assigns can change them during specific statements.
* These are some common strength pairs that are used as defaults when
* the user is not otherwise specific.
*/
static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
%}
%union {
@@ -818,7 +818,6 @@ expr_primary
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
| identifier
{ PEIdent*tmp = new PEIdent(*$1);
@@ -901,6 +900,20 @@ function_item
@1.text, @1.first_line);
$$ = tmp;
}
| K_output range_opt list_of_variables ';'
{ svector<PWire*>*tmp
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
@1.text, @1.first_line);
$$ = tmp;
yyerror(@1, "Functions may not have output ports.");
}
| K_inout range_opt list_of_variables ';'
{ svector<PWire*>*tmp
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
@1.text, @1.first_line);
$$ = tmp;
yyerror(@1, "Functions may not have inout ports.");
}
| block_item_decl
{ $$ = 0; }
;
@@ -1204,16 +1217,11 @@ module_item
}
}
| net_type range_delay net_decl_assigns ';'
{ pform_makewire(@1, $2.range, $2.delay, $3, $1);
{ pform_makewire(@1, $2.range, $2.delay, str_strength,
$3, $1);
}
| net_type drive_strength { decl_strength = $2;} net_decl_assigns ';'
{ pform_makewire(@1, 0, 0, $4, $1);
/* The strengths are handled in the
net_decl_assigns using the decl_strength that I
set in the rule. Right here, just restore the
defaults for other rules. */
decl_strength.str0 = PGate::STRONG;
decl_strength.str1 = PGate::STRONG;
| net_type drive_strength net_decl_assigns ';'
{ pform_makewire(@1, 0, 0, $2, $3, $1);
}
| K_trireg charge_strength_opt range_delay list_of_variables ';'
{ yyerror(@1, "sorry: trireg nets not supported.");
@@ -1241,11 +1249,11 @@ module_item
three-value delay. These rules handle the different cases. */
| gatetype gate_instance_list ';'
{ pform_makegates($1, decl_strength, 0, $2);
{ pform_makegates($1, str_strength, 0, $2);
}
| gatetype delay3 gate_instance_list ';'
{ pform_makegates($1, decl_strength, $2, $3);
{ pform_makegates($1, str_strength, $2, $3);
}
| gatetype drive_strength gate_instance_list ';'
@@ -1260,10 +1268,10 @@ module_item
strengths are limited. */
| K_pullup gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, decl_strength, 0, $2);
{ pform_makegates(PGBuiltin::PULLUP, pull_strength, 0, $2);
}
| K_pulldown gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, decl_strength, 0, $2);
{ pform_makegates(PGBuiltin::PULLDOWN, pull_strength, 0, $2);
}
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
@@ -2246,6 +2254,11 @@ statement
$$ = tmp;
}
}
| '@' '*' statement_opt
{ yyerror(@2, "sorry: Combinational event control "
"is not supported yet.");
$$ = $3;
}
| lpvalue '=' expression ';'
{ PAssign*tmp = new PAssign($1,$3);
tmp->set_file(@1.text);
+45 -15
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform.cc,v 1.87 2001/12/07 05:03:13 steve Exp $"
#ident "$Id: pform.cc,v 1.90 2002/01/31 04:10:15 steve Exp $"
#endif
# include "config.h"
@@ -401,8 +401,6 @@ static void pform_set_net_range(const char*name,
const svector<PExpr*>*range,
bool signed_flag)
{
assert(range);
assert(range->count() == 2);
PWire*cur = pform_cur_module->get_wire(hier_name(name));
if (cur == 0) {
@@ -410,9 +408,17 @@ static void pform_set_net_range(const char*name,
return;
}
assert((*range)[0]);
assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1]);
if (range == 0) {
/* This is the special case that we really mean a
scalar. Set a fake range. */
cur->set_range(0, 0);
} else {
assert(range->count() == 2);
assert((*range)[0]);
assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1]);
}
cur->set_signed(signed_flag);
}
@@ -756,8 +762,7 @@ void pform_makewire(const vlltype&li,
; cur ++ ) {
char*txt = *cur;
pform_makewire(li, txt, type);
if (range)
pform_set_net_range(txt, range, false);
pform_set_net_range(txt, range, false);
free(txt);
}
@@ -769,16 +774,13 @@ void pform_makewire(const vlltype&li,
void pform_makewire(const vlltype&li,
svector<PExpr*>*range,
svector<PExpr*>*delay,
str_pair_t str,
net_decl_assign_t*decls,
NetNet::Type type)
{
net_decl_assign_t*first = decls->next;
decls->next = 0;
struct str_pair_t str;
str.str0 = PGate::STRONG;
str.str1 = PGate::STRONG;
while (first) {
net_decl_assign_t*next = first->next;
@@ -805,14 +807,33 @@ void pform_set_port_type(const char*nm, NetNet::PortType pt,
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::IMPLICIT, pt);
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT);
cur->set_file(file);
cur->set_lineno(lineno);
pform_cur_module->add_wire(cur);
}
if (! cur->set_port_type(pt))
VLerror("error setting port direction.");
switch (cur->get_port_type()) {
case NetNet::PIMPLICIT:
if (! cur->set_port_type(pt))
VLerror("error setting port direction.");
break;
case NetNet::NOT_A_PORT:
cerr << file << ":" << lineno << ": error: "
<< "port " << name << " is not in the port list."
<< endl;
error_count += 1;
break;
default:
cerr << file << ":" << lineno << ": error: "
<< "port " << name << " already has a port declaration."
<< endl;
error_count += 1;
break;
}
}
/*
@@ -1158,6 +1179,15 @@ int pform_parse(const char*path, FILE*file)
/*
* $Log: pform.cc,v $
* Revision 1.90 2002/01/31 04:10:15 steve
* Detect duplicate port declarations.
*
* Revision 1.89 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.88 2002/01/12 04:03:39 steve
* Drive strengths for continuous assignments.
*
* Revision 1.87 2001/12/07 05:03:13 steve
* Support integer for function return value.
*
+5 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform.h,v 1.54 2001/12/07 05:03:13 steve Exp $"
#ident "$Id: pform.h,v 1.55 2002/01/12 04:03:39 steve Exp $"
#endif
# include "netlist.h"
@@ -147,6 +147,7 @@ extern void pform_makewire(const struct vlltype&li,
extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range,
svector<PExpr*>*delay,
str_pair_t str,
net_decl_assign_t*assign_list,
NetNet::Type type);
extern void pform_make_reginit(const struct vlltype&li,
@@ -218,6 +219,9 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.55 2002/01/12 04:03:39 steve
* Drive strengths for continuous assignments.
*
* Revision 1.54 2001/12/07 05:03:13 steve
* Support integer for function return value.
*
+15 -6
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform_dump.cc,v 1.68 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.69 2002/01/26 05:28:28 steve Exp $"
#endif
# include "config.h"
@@ -227,11 +227,17 @@ void PWire::dump(ostream&out) const
assert(msb_.count() == lsb_.count());
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
assert(msb_[idx]);
if (lsb_[idx])
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
else
out << " [" << *msb_[idx] << "]";
if (msb_[idx] == 0) {
assert(lsb_[idx] == 0);
out << " <scalar>";
} else {
if (lsb_[idx])
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
else
out << " [" << *msb_[idx] << "]";
}
}
out << " " << hname_;
@@ -814,6 +820,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.69 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.68 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
+1 -1
View File
@@ -1,7 +1,7 @@
PKG="IVLver"
NAME="verilog"
ARCH="sparc"
VERSION="0.5"
VERSION="0.6"
CATEGORY="application"
VENDOR="Icarus.com"
EMAIL="[email protected]"
+1
View File
@@ -15,6 +15,7 @@ f none include/vvm_signal.h 0644 bin bin
f none include/vvm_thread.h 0644 bin bin
d none lib 0755 bin bin
d none lib/ivl 0755 bin bin
f none lib/ivl/fpga.tgt 0644 bin bin
f none lib/ivl/iverilog.conf 0644 bin bin
f none lib/ivl/ivl 0755 bin bin
f none lib/ivl/ivlpp 0755 bin bin
+15 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll-api.cc,v 1.73 2001/12/06 03:11:00 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.75 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -272,6 +272,7 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
case IVL_EX_SELECT:
return net->u_.binary_.lef_;
case IVL_EX_BITSEL:
@@ -298,6 +299,7 @@ extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
case IVL_EX_SELECT:
return net->u_.binary_.rig_;
case IVL_EX_TERNARY:
@@ -564,6 +566,7 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
assert(idx < net->u_.arith.width);
@@ -599,6 +602,7 @@ extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx)
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
assert(idx < net->u_.arith.width);
@@ -637,6 +641,7 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
switch (net->type) {
case IVL_LPM_ADD:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
assert(idx < net->u_.arith.width);
@@ -756,6 +761,7 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
return net->u_.arith.width;
@@ -1446,6 +1452,14 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.75 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.74 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.73 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
+32 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) & !defined(macintosh)
#ident "$Id: t-dll-expr.cc,v 1.20 2001/10/23 04:22:41 steve Exp $"
#ident "$Id: t-dll-expr.cc,v 1.22 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -127,7 +127,7 @@ void dll_target::expr_const(const NetEConst*net)
char*bits;
expr_->type_ = IVL_EX_NUMBER;
expr_->width_= net->expr_width();
expr_->signed_ = val.has_sign()? 1 : 0;
expr_->signed_ = net->has_sign()? 1 : 0;
expr_->u_.number_.bits_ = bits = (char*)malloc(expr_->width_);
for (idx = 0 ; idx < expr_->width_ ; idx += 1)
switch (val.get(idx)) {
@@ -161,6 +161,28 @@ void dll_target::expr_scope(const NetEScope*net)
expr_->u_.scope_.scope = lookup_scope_(net->scope());
}
void dll_target::expr_select(const NetESelect*net)
{
assert(expr_ == 0);
net->sub_expr()->expr_scan(this);
ivl_expr_t left = expr_;
expr_ = 0;
net->select()->expr_scan(this);
ivl_expr_t rght = expr_;
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
assert(expr_);
expr_->type_ = IVL_EX_SELECT;
expr_->width_= net->expr_width();
expr_->signed_ = net->has_sign()? 1 : 0;
expr_->u_.binary_.lef_ = left;
expr_->u_.binary_.rig_ = rght;
}
void dll_target::expr_sfunc(const NetESFunc*net)
{
assert(expr_ == 0);
@@ -347,6 +369,14 @@ void dll_target::expr_unary(const NetEUnary*net)
/*
* $Log: t-dll-expr.cc,v $
* Revision 1.22 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.21 2001/12/31 00:08:14 steve
* Support $signed cast of expressions.
*
* Revision 1.20 2001/10/23 04:22:41 steve
* Support bit selects of non-0 lsb for vectors.
*
+16 -4
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll-proc.cc,v 1.40 2001/11/14 03:28:49 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.41 2002/01/19 19:02:08 steve Exp $"
#endif
# include "config.h"
@@ -421,7 +421,7 @@ bool dll_target::proc_cassign(const NetCAssign*net)
return true;
}
void dll_target::proc_condit(const NetCondit*net)
bool dll_target::proc_condit(const NetCondit*net)
{
assert(stmt_cur_);
assert(stmt_cur_->type_ == IVL_ST_NONE);
@@ -438,12 +438,13 @@ void dll_target::proc_condit(const NetCondit*net)
ivl_statement_t save_cur_ = stmt_cur_;
stmt_cur_ = save_cur_->u_.condit_.stmt_+0;
net->emit_recurse_if(this);
bool flag = net->emit_recurse_if(this);
stmt_cur_ = save_cur_->u_.condit_.stmt_+1;
net->emit_recurse_else(this);
flag = flag && net->emit_recurse_else(this);
stmt_cur_ = save_cur_;
return flag;
}
bool dll_target::proc_deassign(const NetDeassign*net)
@@ -531,8 +532,16 @@ bool dll_target::proc_force(const NetForce*net)
calloc(1, sizeof(struct ivl_lval_s));
const NetNet*lsig = net->lval();
assert(lsig);
ivl_signal_t sig = find_signal(des_, lsig);
assert(sig);
if (sig->type_ != IVL_SIT_REG) {
cerr << net->get_line() << ": internal error: Sorry, "
<< "force to nets not supported by this target."
<< endl;
return false;
}
assert(sig->type_ == IVL_SIT_REG);
stmt_cur_->u_.cassign_.lval[0].width_ = lsig->pin_count();
@@ -784,6 +793,9 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.41 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.40 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
+241 -14
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll.cc,v 1.71 2001/12/06 03:11:00 steve Exp $"
#ident "$Id: t-dll.cc,v 1.79 2002/01/23 04:54:37 steve Exp $"
#endif
# include "config.h"
@@ -68,7 +68,7 @@ const char *dlerror(void)
}
#elif defined(HAVE_DLFCN_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_NOW); }
{ return dlopen(name,RTLD_LAZY); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{ return dlsym(dll, nm); }
@@ -96,6 +96,45 @@ inline const char*dlerror(void)
static struct dll_target dll_target_obj;
static void drive_from_link(const Link&lnk, ivl_drive_t&drv0, ivl_drive_t&drv1)
{
switch (lnk.drive0()) {
case Link::HIGHZ:
drv0 = IVL_DR_HiZ;
break;
case Link::WEAK:
drv0 = IVL_DR_WEAK;
break;
case Link::PULL:
drv0 = IVL_DR_PULL;
break;
case Link::STRONG:
drv0 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
drv0 = IVL_DR_SUPPLY;
break;
}
switch (lnk.drive1()) {
case Link::HIGHZ:
drv1 = IVL_DR_HiZ;
break;
case Link::WEAK:
drv1 = IVL_DR_WEAK;
break;
case Link::PULL:
drv1 = IVL_DR_PULL;
break;
case Link::STRONG:
drv1 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
drv1 = IVL_DR_SUPPLY;
break;
}
}
/*
* This function locates an ivl_scope_t object that matches the
* NetScope object. The search works by looking for the parent scope,
@@ -124,10 +163,13 @@ static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur)
ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
{
unsigned i;
ivl_scope_t scope = NULL;
for (i = 0; i < des.nroots_ && scope == NULL; i++)
assert(cur);
ivl_scope_t scope = 0;
for (unsigned i = 0; i < des.nroots_ && scope == 0; i += 1) {
assert(des.roots_[i]);
scope = find_scope_from_root(des.roots_[i], cur);
}
return scope;
}
@@ -247,7 +289,9 @@ static void nexus_sig_add(ivl_nexus_t nex, ivl_signal_t net, unsigned pin)
nex->ptrs_[top-1].l.sig= net;
}
static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
static ivl_nexus_ptr_t nexus_log_add(ivl_nexus_t nex,
ivl_net_logic_t net,
unsigned pin)
{
unsigned top = nex->nptr_ + 1;
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
@@ -259,9 +303,12 @@ static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
nex->ptrs_[top-1].drive1 = (pin == 0)? IVL_DR_STRONG : IVL_DR_HiZ;
nex->ptrs_[top-1].pin_ = pin;
nex->ptrs_[top-1].l.log= net;
return nex->ptrs_ + top - 1;
}
static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin)
static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin,
ivl_drive_t drive0, ivl_drive_t drive1)
{
unsigned top = nex->nptr_ + 1;
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
@@ -269,8 +316,8 @@ static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin)
nex->nptr_ = top;
nex->ptrs_[top-1].type_= __NEXUS_PTR_CON;
nex->ptrs_[top-1].drive0 = IVL_DR_STRONG;
nex->ptrs_[top-1].drive1 = IVL_DR_STRONG;
nex->ptrs_[top-1].drive0 = drive0;
nex->ptrs_[top-1].drive1 = drive1;
nex->ptrs_[top-1].pin_ = pin;
nex->ptrs_[top-1].l.con= net;
}
@@ -470,13 +517,49 @@ bool dll_target::bufz(const NetBUFZ*net)
assert(net->pin(0).nexus()->t_cookie());
obj->pins_[0] = (ivl_nexus_t) net->pin(0).nexus()->t_cookie();
nexus_log_add(obj->pins_[0], obj, 0);
ivl_nexus_ptr_t out_ptr = nexus_log_add(obj->pins_[0], obj, 0);
assert(net->pin(1).nexus()->t_cookie());
obj->pins_[1] = (ivl_nexus_t) net->pin(1).nexus()->t_cookie();
nexus_log_add(obj->pins_[1], obj, 1);
switch (net->pin(0).drive0()) {
case Link::HIGHZ:
out_ptr->drive0 = IVL_DR_HiZ;
break;
case Link::WEAK:
out_ptr->drive0 = IVL_DR_WEAK;
break;
case Link::PULL:
out_ptr->drive0 = IVL_DR_PULL;
break;
case Link::STRONG:
out_ptr->drive0 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
out_ptr->drive0 = IVL_DR_SUPPLY;
break;
}
switch (net->pin(0).drive1()) {
case Link::HIGHZ:
out_ptr->drive1 = IVL_DR_HiZ;
break;
case Link::WEAK:
out_ptr->drive1 = IVL_DR_WEAK;
break;
case Link::PULL:
out_ptr->drive1 = IVL_DR_PULL;
break;
case Link::STRONG:
out_ptr->drive1 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
out_ptr->drive1 = IVL_DR_SUPPLY;
break;
}
/* Attach the logic device to the scope that contains it. */
assert(net->scope());
@@ -602,11 +685,52 @@ void dll_target::logic(const NetLogic*net)
obj->npins_ = net->pin_count();
obj->pins_ = new ivl_nexus_t[obj->npins_];
ivl_nexus_ptr_t out_ptr = 0;
for (unsigned idx = 0 ; idx < obj->npins_ ; idx += 1) {
const Nexus*nex = net->pin(idx).nexus();
assert(nex->t_cookie());
obj->pins_[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_log_add(obj->pins_[idx], obj, idx);
ivl_nexus_ptr_t tmp = nexus_log_add(obj->pins_[idx], obj, idx);
if (idx == 0)
out_ptr = tmp;
}
switch (net->pin(0).drive0()) {
case Link::HIGHZ:
out_ptr->drive0 = IVL_DR_HiZ;
break;
case Link::WEAK:
out_ptr->drive0 = IVL_DR_WEAK;
break;
case Link::PULL:
out_ptr->drive0 = IVL_DR_PULL;
break;
case Link::STRONG:
out_ptr->drive0 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
out_ptr->drive0 = IVL_DR_SUPPLY;
break;
}
switch (net->pin(0).drive1()) {
case Link::HIGHZ:
out_ptr->drive1 = IVL_DR_HiZ;
break;
case Link::WEAK:
out_ptr->drive1 = IVL_DR_WEAK;
break;
case Link::PULL:
out_ptr->drive1 = IVL_DR_PULL;
break;
case Link::STRONG:
out_ptr->drive1 = IVL_DR_STRONG;
break;
case Link::SUPPLY:
out_ptr->drive1 = IVL_DR_SUPPLY;
break;
}
assert(net->scope());
@@ -1064,6 +1188,73 @@ void dll_target::lpm_divide(const NetDivide*net)
scope_add_lpm(obj->scope, obj);
}
void dll_target::lpm_modulo(const NetModulo*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_MOD;
obj->name = strdup(net->name());
assert(net->scope());
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
unsigned wid = net->width_r();
if (wid < net->width_a())
wid = net->width_a();
if (wid < net->width_b())
wid = net->width_b();
obj->u_.arith.width = wid;
obj->u_.arith.q = new ivl_nexus_t[3 * obj->u_.arith.width];
obj->u_.arith.a = obj->u_.arith.q + obj->u_.arith.width;
obj->u_.arith.b = obj->u_.arith.a + obj->u_.arith.width;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
const Nexus*nex;
if (idx < net->width_r()) {
nex = net->pin_Result(idx).nexus();
assert(nex->t_cookie());
obj->u_.arith.q[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.q[idx], obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG);
} else {
obj->u_.arith.q[idx] = 0;
}
if (idx < net->width_a()) {
nex = net->pin_DataA(idx).nexus();
assert(nex);
assert(nex->t_cookie());
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} else {
obj->u_.arith.a[idx] = 0;
}
if (idx < net->width_b()) {
nex = net->pin_DataB(idx).nexus();
assert(nex);
assert(nex->t_cookie());
obj->u_.arith.b[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.arith.b[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
} else {
obj->u_.arith.b[idx] = 0;
}
}
scope_add_lpm(obj->scope, obj);
}
void dll_target::lpm_ff(const NetFF*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
@@ -1302,6 +1493,10 @@ void dll_target::lpm_mult(const NetMult*net)
scope_add_lpm(obj->scope, obj);
}
/*
* Hook up the mux devices so that the select expression selects the
* correct sub-expression with the ivl_lpm_data2 function.
*/
void dll_target::lpm_mux(const NetMux*net)
{
ivl_lpm_t obj = new struct ivl_lpm_s;
@@ -1417,20 +1612,27 @@ bool dll_target::net_const(const NetConst*net)
case can be handled more efficiently without allocating
array space. */
if (obj->width_ == 1) {
ivl_drive_t drv0, drv1;
drive_from_link(net->pin(0), drv0, drv1);
const Nexus*nex = net->pin(0).nexus();
assert(nex->t_cookie());
obj->n.pin_ = (ivl_nexus_t) nex->t_cookie();
nexus_con_add(obj->n.pin_, obj, 0);
nexus_con_add(obj->n.pin_, obj, 0, drv0, drv1);
} else {
obj->n.pins_ = new ivl_nexus_t[obj->width_];
for (unsigned idx = 0 ; idx < obj->width_ ; idx += 1) {
if (! net->pin(idx).is_linked())
continue;
ivl_drive_t drv0, drv1;
drive_from_link(net->pin(idx), drv0, drv1);
const Nexus*nex = net->pin(idx).nexus();
assert(nex->t_cookie());
obj->n.pins_[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_con_add(obj->n.pins_[idx], obj, idx);
nexus_con_add(obj->n.pins_[idx], obj, idx, drv0, drv1);
}
}
@@ -1605,7 +1807,7 @@ void dll_target::signal(const NetNet*net)
case NetNet::WIRE:
case NetNet::IMPLICIT:
obj->type_ = IVL_SIT_WIRE;
obj->type_ = IVL_SIT_TRI;
break;
case NetNet::WOR:
@@ -1674,6 +1876,31 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.79 2002/01/23 04:54:37 steve
* Load modules with RTLD_LAZY
*
* Revision 1.78 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.77 2002/01/12 04:03:09 steve
* Make BUFZ device strengths available.
*
* Revision 1.76 2002/01/06 03:15:43 steve
* Constant values have drive strengths.
*
* Revision 1.75 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.74 2001/12/18 05:34:02 steve
* Comments about MUX synthesis.
*
* Revision 1.73 2001/12/15 02:13:17 steve
* The IVL_SIT_WIRE type does not exist, it is a
* synonym for IVL_SIT_TRI.
*
* Revision 1.72 2001/12/14 02:05:13 steve
* Parse and handle drive strengths of gates to vvp.
*
* Revision 1.71 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
+15 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll.h,v 1.72 2001/12/06 03:11:01 steve Exp $"
#ident "$Id: t-dll.h,v 1.75 2002/01/28 00:52:41 steve Exp $"
#endif
# include "target.h"
@@ -75,6 +75,7 @@ struct dll_target : public target_t, public expr_scan_t {
void lpm_compare(const NetCompare*);
void lpm_divide(const NetDivide*);
void lpm_ff(const NetFF*);
void lpm_modulo(const NetModulo*);
void lpm_mult(const NetMult*);
void lpm_mux(const NetMux*);
void lpm_ram_dq(const NetRamDq*);
@@ -107,7 +108,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool proc_block(const NetBlock*);
void proc_case(const NetCase*);
bool proc_cassign(const NetCAssign*);
void proc_condit(const NetCondit*);
bool proc_condit(const NetCondit*);
bool proc_deassign(const NetDeassign*);
bool proc_delay(const NetPDelay*);
bool proc_disable(const NetDisable*);
@@ -130,6 +131,7 @@ struct dll_target : public target_t, public expr_scan_t {
void expr_memory(const NetEMemory*);
void expr_const(const NetEConst*);
void expr_scope(const NetEScope*);
void expr_select(const NetESelect*);
void expr_sfunc(const NetESFunc*);
void expr_subsignal(const NetEBitSel*);
void expr_ternary(const NetETernary*);
@@ -589,6 +591,17 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.75 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.74 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.73 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.72 2001/12/06 03:11:01 steve
* Add ivl_logic_delay function to ivl_target.
*
+8 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-vvm.cc,v 1.213 2001/10/14 03:50:53 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.214 2002/01/19 19:02:08 steve Exp $"
#endif
# include "config.h"
@@ -190,7 +190,7 @@ class target_vvm : public target_t {
virtual void proc_case(const NetCase*net);
void proc_case_fun(ostream&os, const NetCase*net);
virtual bool proc_cassign(const NetCAssign*);
virtual void proc_condit(const NetCondit*);
virtual bool proc_condit(const NetCondit*);
void proc_condit_fun(ostream&os, const NetCondit*);
virtual bool proc_deassign(const NetDeassign*);
virtual bool proc_delay(const NetPDelay*);
@@ -3195,11 +3195,11 @@ bool target_vvm::proc_cassign(const NetCAssign*dev)
return true;
}
void target_vvm::proc_condit(const NetCondit*net)
bool target_vvm::proc_condit(const NetCondit*net)
{
if (function_def_flag_) {
proc_condit_fun(out, net);
return;
return true;
}
string expr = emit_proc_rval(this, net->expr());
@@ -3250,6 +3250,7 @@ void target_vvm::proc_condit(const NetCondit*net)
defn << "static bool " << thread_class_ << "_step_" << out_step <<
"_(vvm_thread*thr) {" << endl;
return true;
}
void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
@@ -3658,6 +3659,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.214 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.213 2001/10/14 03:50:53 steve
* vvm support for pullup/down gates (PR#288)
*
+17 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.cc,v 1.57 2001/08/25 23:50:03 steve Exp $"
#ident "$Id: target.cc,v 1.59 2002/01/28 00:52:41 steve Exp $"
#endif
# include "config.h"
@@ -216,11 +216,12 @@ bool target_t::proc_cassign(const NetCAssign*dev)
return false;
}
void target_t::proc_condit(const NetCondit*condit)
bool target_t::proc_condit(const NetCondit*condit)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled conditional:" << endl;
condit->dump(cerr, 6);
return false;
}
bool target_t::proc_deassign(const NetDeassign*dev)
@@ -339,6 +340,12 @@ void expr_scan_t::expr_scope(const NetEScope*)
"unhandled expr_scope." << endl;
}
void expr_scan_t::expr_select(const NetESelect*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
"unhandled expr_select." << endl;
}
void expr_scan_t::expr_sfunc(const NetESFunc*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
@@ -383,6 +390,14 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.59 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.58 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.57 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
+11 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.h,v 1.54 2001/08/25 23:50:03 steve Exp $"
#ident "$Id: target.h,v 1.56 2002/01/28 00:52:41 steve Exp $"
#endif
# include "netlist.h"
@@ -105,7 +105,7 @@ struct target_t {
virtual bool proc_block(const NetBlock*);
virtual void proc_case(const NetCase*);
virtual bool proc_cassign(const NetCAssign*);
virtual void proc_condit(const NetCondit*);
virtual bool proc_condit(const NetCondit*);
virtual bool proc_deassign(const NetDeassign*);
virtual bool proc_delay(const NetPDelay*);
virtual bool proc_disable(const NetDisable*);
@@ -132,6 +132,7 @@ struct expr_scan_t {
virtual void expr_concat(const NetEConcat*);
virtual void expr_memory(const NetEMemory*);
virtual void expr_scope(const NetEScope*);
virtual void expr_select(const NetESelect*);
virtual void expr_sfunc(const NetESFunc*);
virtual void expr_signal(const NetESignal*);
virtual void expr_subsignal(const NetEBitSel*);
@@ -162,6 +163,14 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.56 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.55 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.54 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
+7 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: stub.c,v 1.50 2001/09/30 16:45:10 steve Exp $"
#ident "$Id: stub.c,v 1.51 2001/12/15 02:13:17 steve Exp $"
#endif
# include "config.h"
@@ -408,8 +408,8 @@ static void show_signal(ivl_signal_t net)
case IVL_SIT_REG:
type = "reg";
break;
case IVL_SIT_WIRE:
type = "wire";
case IVL_SIT_TRI:
type = "tri";
break;
case IVL_SIT_SUPPLY0:
type = "supply0";
@@ -606,6 +606,10 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.51 2001/12/15 02:13:17 steve
* The IVL_SIT_WIRE type does not exist, it is a
* synonym for IVL_SIT_TRI.
*
* Revision 1.50 2001/09/30 16:45:10 steve
* Fix some Cygwin DLL handling. (Venkat Iyer)
*
+6 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: verilog.c,v 1.25 2001/09/30 16:45:10 steve Exp $"
#ident "$Id: verilog.c,v 1.26 2001/12/15 02:13:17 steve Exp $"
#endif
# include "config.h"
@@ -60,7 +60,7 @@ static void draw_scoped_objects(ivl_design_t des)
fprintf(out, " reg %s;\n",
ivl_signal_basename(sig));
break;
case IVL_SIT_WIRE:
case IVL_SIT_TRI:
fprintf(out, " wire %s;\n", ivl_signal_basename(sig));
break;
default:
@@ -439,6 +439,10 @@ int target_design(ivl_design_t des)
/*
* $Log: verilog.c,v $
* Revision 1.26 2001/12/15 02:13:17 steve
* The IVL_SIT_WIRE type does not exist, it is a
* synonym for IVL_SIT_TRI.
*
* Revision 1.25 2001/09/30 16:45:10 steve
* Fix some Cygwin DLL handling. (Venkat Iyer)
*
+67 -66
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: eval_expr.c,v 1.53 2001/11/19 04:25:46 steve Exp $"
#ident "$Id: eval_expr.c,v 1.56 2002/02/03 05:53:00 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -977,6 +977,55 @@ static struct vector_info draw_memory_expr(ivl_expr_t exp, unsigned wid)
return res;
}
static struct vector_info draw_select_expr(ivl_expr_t exp, unsigned wid)
{
struct vector_info subv, shiv, res;
ivl_expr_t sube = ivl_expr_oper1(exp);
ivl_expr_t shift = ivl_expr_oper2(exp);
/* Evaluate the sub-expression. */
subv = draw_eval_expr(sube);
/* Any bit select of a constant zero is another constant zero,
so short circuit and return the value we know. */
if (subv.base == 0) {
subv.wid = wid;
return subv;
}
/* Evaluate the bit select base expression and store the
result into index register 0. */
shiv = draw_eval_expr(shift);
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid);
clr_vector(shiv);
/* If the subv result is a magic constant, then make a copy in
writeable vector space and work from there instead. */
if (subv.base < 4) {
res.base = allocate_vector(subv.wid);
res.wid = wid;
fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base,
subv.base, res.wid);
subv = res;
}
fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", subv.base, subv.wid);
assert(subv.wid >= wid);
if (subv.wid > wid) {
res.base = subv.base;
res.wid = wid;
subv.base += wid;
clr_vector(subv);
} else if (subv.wid == wid) {
res = subv;
}
return res;
}
static struct vector_info draw_ternary_expr(ivl_expr_t exp, unsigned wid)
{
struct vector_info res, tmp;
@@ -1109,6 +1158,8 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
case IVL_EX_SFUNC:
if (strcmp("$time", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $time");
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $stime");
else
fprintf(vvp_out, ", ?");
continue;
@@ -1413,6 +1464,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid)
res = draw_number_expr(exp, wid);
break;
case IVL_EX_SELECT:
res = draw_select_expr(exp, wid);
break;
case IVL_EX_SIGNAL:
res = draw_signal_expr(exp, wid);
break;
@@ -1448,6 +1503,17 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
/*
* $Log: eval_expr.c,v $
* Revision 1.56 2002/02/03 05:53:00 steve
* Fix parameter bit select check for magic constants.
*
* Revision 1.55 2002/01/28 00:52:42 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.54 2002/01/11 05:23:05 steve
* Handle certain special cases of stime.
*
* Revision 1.53 2001/11/19 04:25:46 steve
* Handle padding out of logical values.
*
@@ -1494,70 +1560,5 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
*
* Revision 1.39 2001/07/27 02:41:56 steve
* Fix binding of dangling function ports. do not elide them.
*
* Revision 1.38 2001/07/22 19:33:51 steve
* Handle repeat for concatenation expressions.
*
* Revision 1.37 2001/07/22 00:17:50 steve
* Support the NetESubSignal expressions in vvp.tgt.
*
* Revision 1.36 2001/07/09 15:38:35 steve
* Properly step through wide inputs. (Stephan Boettcher)
*
* Revision 1.35 2001/07/07 20:20:10 steve
* Pass parameters to system functions.
*
* Revision 1.34 2001/06/30 21:07:26 steve
* Support non-const right shift (unsigned).
*
* Revision 1.33 2001/06/23 18:40:34 steve
* Generate %shiftl instructions for shift.
*
* Revision 1.32 2001/06/21 04:53:59 steve
* Escaped identifiers in behavioral expressions. (Stephan Boettcher)
*
* Revision 1.31 2001/06/18 01:09:32 steve
* More behavioral unary reduction operators.
* (Stephan Boettcher)
*
* Revision 1.30 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.29 2001/05/24 04:20:10 steve
* Add behavioral modulus.
*
* Revision 1.28 2001/05/20 01:18:38 steve
* Implement reduction nor.
*
* Revision 1.27 2001/05/20 01:02:55 steve
* Initial support for system functions.
*
* Revision 1.26 2001/05/17 04:37:02 steve
* Behavioral ternary operators for vvp.
*
* Revision 1.25 2001/05/10 00:26:53 steve
* VVP support for memories in expressions,
* including general support for thread bit
* vectors as system task parameters.
* (Stephan Boettcher)
*
* Revision 1.24 2001/05/06 17:54:33 steve
* Behavioral code to read memories. (Stephan Boettcher)
*
* Revision 1.23 2001/05/02 01:57:25 steve
* Support behavioral subtraction.
*
* Revision 1.22 2001/05/01 02:07:34 steve
* Comparisons cant leave their results in the opcode
* result area or their values will be clobbered by other
* parts of a complex expression.
*
* Revision 1.21 2001/04/30 05:11:18 steve
* OR is %or. Get this right.
*
* Revision 1.20 2001/04/29 20:47:39 steve
* Evalulate logical or (||)
*/
+6 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_process.c,v 1.51 2001/12/05 05:41:20 steve Exp $"
#ident "$Id: vvp_process.c,v 1.52 2002/01/11 05:23:05 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -877,6 +877,8 @@ static int show_system_task_call(ivl_statement_t net)
case IVL_EX_SFUNC:
if (strcmp("$time", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $time");
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $time");
else
fprintf(vvp_out, ", ?");
continue;
@@ -1100,6 +1102,9 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.52 2002/01/11 05:23:05 steve
* Handle certain special cases of stime.
*
* Revision 1.51 2001/12/05 05:41:20 steve
* Make sure fork labels are globally unique.
*
+223 -80
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_scope.c,v 1.57 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.64 2002/01/12 17:49:41 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -126,6 +126,77 @@ const char *vvp_mangle_name(const char *id)
return out;
}
ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
{
unsigned idx;
ivl_signal_type_t out = IVL_SIT_TRI;
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_signal_type_t stype;
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
stype = ivl_signal_type(sig);
if (stype == IVL_SIT_REG)
continue;
if (stype == IVL_SIT_TRI)
continue;
if (stype == IVL_SIT_NONE)
continue;
out = stype;
}
return out;
}
ivl_nexus_ptr_t ivl_logic_pin_ptr(ivl_net_logic_t net, unsigned pin)
{
ivl_nexus_t nex = ivl_logic_pin(net, pin);
unsigned idx;
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
ivl_net_logic_t tmp = ivl_nexus_ptr_log(ptr);
if (tmp == 0)
continue;
if (tmp != net)
continue;
if (ivl_nexus_ptr_pin(ptr) != pin)
continue;
return ptr;
}
assert(0);
return 0;
}
const char*drive_string(ivl_drive_t drive)
{
switch (drive) {
case IVL_DR_HiZ:
return "";
case IVL_DR_SMALL:
return "sm";
case IVL_DR_MEDIUM:
return "me";
case IVL_DR_WEAK:
return "we";
case IVL_DR_LARGE:
return "la";
case IVL_DR_PULL:
return "pu";
case IVL_DR_STRONG:
return "";
case IVL_DR_SUPPLY:
return "su";
}
return "";
}
/*
* The draw_scope function draws the major functional items within a
* scope. This includes the scopes themselves, of course. All the
@@ -171,10 +242,16 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
ivl_lpm_t lpm;
lptr = ivl_nexus_ptr_log(nptr);
if (lptr && (ivl_logic_type(lptr) == IVL_LO_BUFZ) &&
(nptr_pin == 0)) {
return draw_net_input(ivl_logic_pin(lptr, 1));
}
if (lptr && (ivl_logic_type(lptr) == IVL_LO_BUFZ) && (nptr_pin == 0))
do {
if (ivl_nexus_ptr_drive0(nptr) != IVL_DR_STRONG)
break;
if (ivl_nexus_ptr_drive1(nptr) != IVL_DR_STRONG)
break;
return draw_net_input(ivl_logic_pin(lptr, 1));
} while(0);
if (lptr && (ivl_logic_type(lptr) == IVL_LO_PULLDOWN)) {
return "C<pu0>";
@@ -196,18 +273,29 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
return result;
}
if (sptr && (ivl_signal_type(sptr) == IVL_SIT_SUPPLY1)) {
return "C<su1>";
}
if (sptr && (ivl_signal_type(sptr) == IVL_SIT_SUPPLY0)) {
return "C<su0>";
}
cptr = ivl_nexus_ptr_con(nptr);
if (cptr) {
const char*bits = ivl_const_bits(cptr);
sprintf(result, "C<%c>", bits[nptr_pin]);
ivl_drive_t drive;
switch (bits[nptr_pin]) {
case '0':
drive = ivl_nexus_ptr_drive0(nptr);
if (drive == IVL_DR_HiZ)
sprintf(result, "C<z>");
else
sprintf(result, "C<%s0>", drive_string(drive));
break;
case '1':
drive = ivl_nexus_ptr_drive1(nptr);
if (drive == IVL_DR_HiZ)
sprintf(result, "C<z>");
else
sprintf(result, "C<%s1>", drive_string(drive));
break;
default:
sprintf(result, "C<%c>", bits[nptr_pin]);
}
return result;
}
@@ -230,6 +318,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
case IVL_LPM_SUB:
case IVL_LPM_MULT:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1)
if (ivl_lpm_q(lpm, idx) == nex) {
sprintf(result, "L_%s[%u]",
@@ -270,6 +359,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
*/
const char* draw_net_input(ivl_nexus_t nex)
{
ivl_signal_type_t res;
char result[512];
unsigned idx;
int level;
@@ -277,12 +367,44 @@ const char* draw_net_input(ivl_nexus_t nex)
static ivl_nexus_ptr_t *drivers = 0x0;
static unsigned adrivers = 0;
const char*resolv_type;
/* If this nexus already has a label, then its input is
already figured out. Just return the existing label. */
char*nex_private = (char*)ivl_nexus_get_private(nex);
if (nex_private)
return nex_private;
res = signal_type_of_nexus(nex);
switch (res) {
case IVL_SIT_TRI:
resolv_type = "tri";
break;
case IVL_SIT_TRI0:
resolv_type = "tri0";
break;
case IVL_SIT_TRI1:
resolv_type = "tri1";
break;
/* Catch the special cases that the nets are supply
nets. Drive constant values uncomditionally. */
case IVL_SIT_SUPPLY0:
nex_private = "C<su0>";
ivl_nexus_set_private(nex, nex_private);
return nex_private;
case IVL_SIT_SUPPLY1:
nex_private = "C<su1>";
ivl_nexus_set_private(nex, nex_private);
return nex_private;
default:
fprintf(stderr, "vvp.tgt: Unsupported signal type: %u\n", res);
assert(0);
resolv_type = "tri";
break;
}
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t nptr = ivl_nexus_ptr(nex, idx);
@@ -306,14 +428,28 @@ const char* draw_net_input(ivl_nexus_t nex)
/* If the nexus has no drivers, then send a constant HiZ into
the net. */
if (ndrivers == 0) {
nex_private = "C<z>";
switch (res) {
case IVL_SIT_TRI:
nex_private = "C<z>";
break;
case IVL_SIT_TRI0:
nex_private = "C<0>";
break;
case IVL_SIT_TRI1:
nex_private = "C<1>";
break;
default:
assert(0);
}
ivl_nexus_set_private(nex, nex_private);
return nex_private;
}
/* If the nexus has exactly one driver, then simply draw it. */
if (ndrivers == 1) {
/* If the nexus has exactly one driver, then simply draw
it. Note that this will *not* work if the nexus is not a
TRI type nexus. */
if (ndrivers == 1 && res == IVL_SIT_TRI) {
nex_private = strdup(draw_net_input_drive(nex, drivers[0]));
ivl_nexus_set_private(nex, nex_private);
return nex_private;
@@ -328,8 +464,9 @@ const char* draw_net_input(ivl_nexus_t nex)
vvp_mangle_id(ivl_nexus_name(nex)),
level, inst);
else
fprintf(vvp_out, "RS_%s .resolv tri",
vvp_mangle_id(ivl_nexus_name(nex)));
fprintf(vvp_out, "RS_%s .resolv %s",
vvp_mangle_id(ivl_nexus_name(nex)),
resolv_type);
for (idx = inst; idx < ndrivers && idx < inst+4; idx += 1) {
if (level) {
@@ -524,6 +661,9 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
const char*ltype = "?";
const char*lcasc = 0x0;
char identity_val = '0';
ivl_drive_t str0, str1;
int level;
int ninp = ivl_logic_pins(lptr) - 1;
typedef const char*const_charp;
@@ -538,10 +678,23 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
draw_udp_in_scope(lptr);
return;
case IVL_LO_BUFZ:
/* Skip BUFZ objects. Things that have a bufz as input
will use the input to bufz instead. */
return;
case IVL_LO_BUFZ: {
/* Draw bufz objects, but only if the output drive
is different from the input. */
ivl_nexus_ptr_t nptr = ivl_logic_pin_ptr(lptr,0);
ivl_drive_t dr0 = ivl_nexus_ptr_drive0(nptr);
ivl_drive_t dr1 = ivl_nexus_ptr_drive1(nptr);
ltype = "BUFZ";
if (dr0 != IVL_DR_STRONG)
break;
if (dr1 != IVL_DR_STRONG)
break;
return;
}
case IVL_LO_PULLDOWN:
case IVL_LO_PULLUP:
@@ -616,13 +769,11 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
break;
case IVL_LO_NOTIF0:
fprintf(stderr, "vvp.tgt: error: Unhandled logic of type NOTIF0\n");
ltype = "?";
ltype = "NOTIF0";
break;
case IVL_LO_NOTIF1:
fprintf(stderr, "vvp.tgt: error: Unhandled logic of type NOTIF1\n");
ltype = "?";
ltype = "NOTIF1";
break;
default:
@@ -632,6 +783,21 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
break;
}
{ ivl_nexus_t nex = ivl_logic_pin(lptr, 0);
ivl_nexus_ptr_t nptr = 0;
unsigned idx;
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
nptr = ivl_nexus_ptr(nex,idx);
if (ivl_nexus_ptr_log(nptr) != lptr)
continue;
if (ivl_nexus_ptr_pin(nptr) != 0)
continue;
break;
}
str0 = ivl_nexus_ptr_drive0(nptr);
str1 = ivl_nexus_ptr_drive1(nptr);
}
if (!lcasc)
lcasc = ltype;
@@ -656,7 +822,12 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
fprintf(vvp_out, "L_%s .functor %s",
vvp_mangle_id(ivl_logic_name(lptr)),
ltype);
draw_delay(lptr);
if (str0 != IVL_DR_STRONG || str1 != IVL_DR_STRONG)
fprintf(vvp_out, " [%u %u]", str0, str1);
}
for (pdx = inst; pdx < ninp && pdx < inst+4 ; pdx += 1) {
if (level) {
@@ -917,6 +1088,9 @@ static void draw_lpm_add(ivl_lpm_t net)
case IVL_LPM_DIVIDE:
type = "div";
break;
case IVL_LPM_MOD:
type = "mod";
break;
default:
assert(0);
}
@@ -1116,6 +1290,7 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
case IVL_LPM_SUB:
case IVL_LPM_MULT:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
draw_lpm_add(net);
return;
@@ -1235,6 +1410,27 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.64 2002/01/12 17:49:41 steve
* Handle constants with drive strength z
*
* Revision 1.63 2002/01/12 04:03:40 steve
* Drive strengths for continuous assignments.
*
* Revision 1.62 2002/01/06 03:15:43 steve
* Constant values have drive strengths.
*
* Revision 1.61 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.60 2001/12/15 02:13:33 steve
* Support all 3 TRI net types.
*
* Revision 1.59 2001/12/14 06:03:34 steve
* Generate notif functors.
*
* Revision 1.58 2001/12/14 02:05:13 steve
* Parse and handle drive strengths of gates to vvp.
*
* Revision 1.57 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
@@ -1268,58 +1464,5 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
*
* Revision 1.47 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.46 2001/09/14 04:15:46 steve
* Generate code for identity comparators.
*
* Revision 1.45 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*
* Revision 1.44 2001/08/03 17:06:10 steve
* More detailed messages about unsupported things.
*
* Revision 1.43 2001/07/28 03:18:50 steve
* Generate constant symbols for supply nets.
*
* Revision 1.42 2001/07/22 21:31:14 steve
* supply signals give input values.
*
* Revision 1.41 2001/07/18 02:44:39 steve
* Relax driver limit from 64 to forever (Stephan Boettcher)
*
* Revision 1.40 2001/07/16 18:31:49 steve
* Nest resolvers when there are lots of drivers (Stephan Boettcher)
*
* Revision 1.39 2001/07/09 15:38:35 steve
* Properly step through wide inputs. (Stephan Boettcher)
*
* Revision 1.38 2001/07/07 03:01:06 steve
* Generate code for right shift.
*
* Revision 1.37 2001/07/06 04:48:04 steve
* Generate code for structural left shift.
*
* Revision 1.36 2001/06/19 03:01:10 steve
* Add structural EEQ gates (Stephan Boettcher)
*
* Revision 1.35 2001/06/18 03:10:34 steve
* 1. Logic with more than 4 inputs
* 2. Id and name mangling
* 3. A memory leak in draw_net_in_scope()
* (Stephan Boettcher)
*
* Revision 1.34 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.33 2001/06/16 02:41:42 steve
* Generate code to support memory access in continuous
* assignment statements. (Stephan Boettcher)
*
* Revision 1.32 2001/06/15 04:14:19 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.31 2001/06/07 04:20:10 steve
*/
+5 -4
View File
@@ -1,10 +1,10 @@
Summary: Icarus Verilog
Name: verilog
Version: 0.5
Version: 0.6
Release: 0
Copyright: GPL
Group: Applications/Engineering
Source: ftp://icarus.com/pub/eda/verilog/v0.5/verilog-0.5.tar.gz
Source: ftp://icarus.com/pub/eda/verilog/v0.6/verilog-0.6.tar.gz
URL: http://www.icarus.com/eda/verilog/index.html
Packager: Stephen Williams <[email protected]>
@@ -20,7 +20,7 @@ engineering formats, including simulation. It strives to be true
to the IEEE-1364 standard.
%prep
%setup -n verilog-0.5
%setup -n verilog-0.6
%build
./configure --prefix=/usr
@@ -31,7 +31,7 @@ make prefix=$RPM_BUILD_ROOT/usr install
%files
%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt netlist.txt t-dll.txt vpi.txt vvm.txt xnf.txt xilinx-hint.txt
%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt netlist.txt t-dll.txt vpi.txt vvm.txt xnf.txt tgt-fpga/fpga.txt xilinx-hint.txt
%attr(-,root,root) %doc examples/*
%attr(-,root,root) /usr/man/man1/iverilog.1.gz
@@ -44,6 +44,7 @@ make prefix=$RPM_BUILD_ROOT/usr install
%attr(-,root,root) /usr/lib/ivl/system.vpi
%attr(-,root,root) /usr/lib/ivl/null.tgt
%attr(-,root,root) /usr/lib/ivl/vvp.tgt
%attr(-,root,root) /usr/lib/ivl/fpga.tgt
%attr(-,root,root) /usr/lib/ivl/iverilog.conf
%attr(-,root,root) /usr/lib/libvpi.a
%attr(-,root,root) /usr/lib/libvvm.a
+22 -9
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: verinum.cc,v 1.29 2001/11/19 02:54:12 steve Exp $"
#ident "$Id: verinum.cc,v 1.31 2002/02/01 05:09:14 steve Exp $"
#endif
# include "config.h"
@@ -351,15 +351,16 @@ ostream& operator<< (ostream&o, verinum::V v)
*/
ostream& operator<< (ostream&o, const verinum&v)
{
if (v.has_sign()) {
o << "+";
}
/* If the verinum number has a fixed length, dump all the bits
literally. This is how we express the fixed length in the
output. */
if (v.has_len()) {
o << v.len() << "'b";
o << v.len();
if (v.has_sign())
o << "'sb";
else
o << "'b";
if (v.len() == 0) {
o << "0";
return o;
@@ -374,13 +375,19 @@ ostream& operator<< (ostream&o, const verinum&v)
/* If the number is fully defined (no x or z) then print it
out as a decimal number. */
if (v.is_defined()) {
o << "'d" << v.as_ulong();
if (v.has_sign())
o << "'sd" << v.as_ulong();
else
o << "'d" << v.as_ulong();
return o;
}
/* Oh, well. Print the minimum to get the value properly
displayed. */
o << "'b";
if (v.has_sign())
o << "'sb";
else
o << "'b";
if (v.len() == 0) {
o << "0";
@@ -588,7 +595,7 @@ verinum operator - (const verinum&left, const verinum&r)
for (unsigned idx = min ; idx < max ; idx += 1)
val.set(idx, add_with_carry(verinum::V0, right[idx], carry));
val.has_sign(left.has_sign() && r.has_sign());
return val;
}
@@ -786,6 +793,12 @@ verinum::V operator & (verinum::V l, verinum::V r)
/*
* $Log: verinum.cc,v $
* Revision 1.31 2002/02/01 05:09:14 steve
* Propagate sign in unary minus.
*
* Revision 1.30 2001/12/31 00:02:33 steve
* Include s indicator in dump of signed numbers.
*
* Revision 1.29 2001/11/19 02:54:12 steve
* Handle division and modulus by zero while
* evaluating run-time constants.
+417 -43
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_display.c,v 1.31 2001/11/02 05:56:47 steve Exp $"
#ident "$Id: sys_display.c,v 1.34 2002/01/22 00:18:10 steve Exp $"
#endif
# include "config.h"
@@ -30,11 +30,51 @@
struct strobe_cb_info {
char*name;
int default_format;
vpiHandle scope;
vpiHandle*items;
unsigned nitems;
};
// The number of decimal digits needed to represent a
// nr_bits binary number is floor(nr_bits*log_10(2))+1,
// where log_10(2) = 0.30102999566398.... and I approximate
// this transcendental number as 146/485, to avoid the vagaries
// of floating-point. The smallest nr_bits for which this
// approximation fails is 2621,
// 2621*log_10(2)=789.9996, but (2621*146+484)/485=790 (exactly).
// In cases like this, all that happens is we allocate one
// unneeded char for the output. I add a "L" suffix to 146
// to make sure the computation is done as long ints, otherwise
// on a 16-bit int machine (allowed by ISO C) we would mangle
// this computation for bit-length of 224. I'd like to put
// in a test for nr_bits < LONG_MAX/146, but don't know how
// to fail, other than crashing.
//
// In an April 2000 thread in comp.unix.programmer, with subject
// "integer -> string", I <[email protected]> give the 28/93
// approximation, but overstate its accuracy: that version first
// fails when the number of bits is 289, not 671.
//
// This result does not include space for a trailing '\0', if any.
//
inline static int calc_dec_size(int nr_bits, int is_signed)
{
int r;
if (is_signed) --nr_bits;
r = (nr_bits * 146L + 484) / 485;
if (is_signed) ++r;
return r;
}
static int vpi_get_dec_size(vpiHandle item)
{
return calc_dec_size(
vpi_get(vpiSize, item),
vpi_get(vpiSigned, item)==1
);
}
static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
{
if (argv) {
@@ -70,6 +110,7 @@ static int format_str(vpiHandle scope, unsigned int mcd,
s_vpi_value value;
char buf[256];
char*cp = fmt;
char format_char = ' ';
int idx;
assert(fmt);
@@ -87,11 +128,13 @@ static int format_str(vpiHandle scope, unsigned int mcd,
cp += cnt;
} else if (*cp == '%') {
int fsize = -1, ffsize = -1;
int do_num = 0;
int leading_zero = -1, fsize = -1, ffsize = -1;
int do_arg = 0;
cp += 1;
if (isdigit(*cp))
if (*cp == '0')
leading_zero=1;
if (isdigit((int)*cp))
fsize = strtoul(cp, &cp, 10);
if (*cp == '.') {
cp += 1;
@@ -100,61 +143,138 @@ static int format_str(vpiHandle scope, unsigned int mcd,
switch (*cp) {
case 0:
break;
case 'b':
case 'B':
do_num = 1;
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 'b';
do_arg = 1;
value.format = vpiBinStrVal;
cp += 1;
break;
case 'd':
case 'D':
do_num = 1;
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 'd';
do_arg = 1;
value.format = vpiDecStrVal;
cp += 1;
break;
#if 0
case 'f':
do_num = 1;
value.format = vpiDecStrVal;
cp += 1;
break;
#endif
case 'h':
case 'H':
case 'x':
case 'X':
do_num = 1;
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 'h';
do_arg = 1;
value.format = vpiHexStrVal;
cp += 1;
break;
case 'm':
assert(scope);
vpi_mcd_printf(mcd, "%s", vpi_get_str(vpiFullName, scope));
cp += 1;
break;
case 'o':
case 'O':
do_num = 1;
value.format = vpiOctStrVal;
cp += 1;
break;
case 's':
case 'S':
do_num = 1;
case 'c':
case 'C':
if (fsize != -1 && ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
ffsize = -1;
}
format_char = 'c';
do_arg = 1;
value.format = vpiStringVal;
cp += 1;
break;
case 'm':
case 'M':
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
if (fsize == -1)
fsize = 0;
assert(scope);
vpi_mcd_printf(mcd, "%*s",
fsize,
vpi_get_str(vpiFullName, scope));
cp += 1;
break;
case 'o':
case 'O':
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 'o';
do_arg = 1;
value.format = vpiOctStrVal;
cp += 1;
break;
case 's':
case 'S':
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 's';
do_arg = 1;
value.format = vpiStringVal;
cp += 1;
break;
case 't':
case 'T':
do_num = 1;
if (ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
}
format_char = 't';
do_arg = 1;
value.format = vpiDecStrVal;
cp += 1;
break;
case '%':
if (fsize != -1 && ffsize != -1) {
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
fsize = -1;
ffsize = -1;
}
vpi_mcd_printf(mcd, "%%");
cp += 1;
break;
case 'v':
case 'V':
case 'e':
case 'f':
case 'g':
// new Verilog 2001 format specifiers...
case 'l':
case 'L':
case 'u':
case 'U':
case 'z':
case 'Z':
vpi_printf("\nERROR: Unsupported format \"%s\"\n", fmt);
vpi_mcd_printf(mcd, "%c", *cp);
cp += 1;
break;
default:
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
vpi_mcd_printf(mcd, "%c", *cp);
cp += 1;
break;
@@ -163,17 +283,96 @@ static int format_str(vpiHandle scope, unsigned int mcd,
/* If we encountered a numeric format string, then
grab the number value from the next parameter
and display it in the requested format. */
if (do_num) {
if (do_arg) {
if (idx >= argc) {
vpi_printf("\ntoo few arguments for format %s\n",
fmt);
} else {
vpi_get_value(argv[idx++], &value);
if (fsize>0)
vpi_mcd_printf(mcd, "%*s",
fsize, value.value.str);
else
vpi_mcd_printf(mcd, "%s", value.value.str);
vpi_get_value(argv[idx], &value);
switch(format_char){
case 'c':
vpi_mcd_printf(mcd, "%c", value.value.str[strlen(value.value.str)-1]);
break;
case 't':
case 'd':
if (fsize==-1){
// simple %d parameter.
// Size is now determined by the width
// of the vector or integer
fsize = vpi_get_dec_size(argv[idx]);
}
vpi_mcd_printf(mcd, "%*s", fsize,
value.value.str);
break;
case 'b':
case 'h':
case 'x':
case 'o':
if (fsize==-1){
// For hex, oct and binary values, the string is already
// prefixed with the correct number of zeros...
vpi_mcd_printf(mcd, "%s", value.value.str);
}
else{
char* value_str = value.value.str;
if (leading_zero==1){
// Strip away all leading zeros from string
int i=0;
while(i< (strlen(value_str)-1) && value_str[i]=='0')
i++;
value_str += i;
}
vpi_mcd_printf(mcd, "%*s", fsize, value_str);
}
break;
case 's':
if (fsize==-1){
vpi_mcd_printf(mcd, "%s", value.value.str);
}
else{
char* value_str = value.value.str;
if (leading_zero==1){
// Remove leading spaces from the value
// string *except* if the argument is a
// constant string... (hey, that's how
// the commerical guys behave...)
if (!(vpi_get(vpiType, argv[idx]) == vpiConstant
&& vpi_get(vpiConstType, argv[idx]) == vpiStringConst)) {
int i=0;
// Strip away all leading zeros from string
while(i< (strlen(value_str)-1) && value_str[i]==' ')
i++;
value_str += i;
}
}
vpi_mcd_printf(mcd, "%*s", fsize, value_str);
}
break;
default:
if (fsize > 0)
vpi_mcd_printf(mcd, "%*s", fsize,
value.value.str);
else
vpi_mcd_printf(mcd, "%s",
value.value.str);
}
idx++;
}
}
@@ -214,6 +413,7 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
{
s_vpi_value value;
int idx;
int size;
for (idx = 0 ; idx < info->nitems ; idx += 1) {
vpiHandle item = info->items[idx];
@@ -241,15 +441,26 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
case vpiNet:
case vpiReg:
case vpiMemoryWord:
value.format = vpiBinStrVal;
value.format = info->default_format;
vpi_get_value(item, &value);
vpi_mcd_printf(mcd, "%s", value.value.str);
switch(info->default_format){
case vpiDecStrVal:
size = vpi_get_dec_size(item);
vpi_mcd_printf(mcd, "%*s", size, value.value.str);
break;
default:
vpi_mcd_printf(mcd, "%s", value.value.str);
}
break;
case vpiTimeVar:
value.format = vpiTimeVal;
vpi_get_value(item, &value);
vpi_mcd_printf(mcd, "%u", value.value.time->low);
vpi_mcd_printf(mcd, "%20u", value.value.time->low);
break;
default:
@@ -259,6 +470,25 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
}
}
static int get_default_format(char *name)
{
int default_format;
switch(name[ strlen(name)-1 ]){
// writE/strobE or monitoR or displaY/fdisplaY
case 'e':
case 'r':
case 'y': default_format = vpiDecStrVal; break;
case 'h': default_format = vpiHexStrVal; break;
case 'o': default_format = vpiOctStrVal; break;
case 'b': default_format = vpiBinStrVal; break;
default:
assert(0);
}
return default_format;
}
static int sys_display_calltf(char *name)
{
struct strobe_cb_info info;
@@ -268,14 +498,14 @@ static int sys_display_calltf(char *name)
vpiHandle argv = vpi_iterate(vpiArgument, sys);
assert(scope);
info.default_format = get_default_format(name);
info.scope = scope;
array_from_iterator(&info, argv);
do_display(5, &info);
free(info.items);
if (strcmp(name,"$display") == 0)
if (strncmp(name,"$display",8) == 0)
vpi_mcd_printf(5, "\n");
return 0;
@@ -318,6 +548,7 @@ static int sys_strobe_calltf(char*name)
array_from_iterator(info, argv);
info->name = strdup(name);
info->default_format = get_default_format(name);
info->scope= scope;
time.type = vpiSimTime;
@@ -342,7 +573,7 @@ static int sys_strobe_calltf(char*name)
* though that monitor may be watching many variables).
*/
static struct strobe_cb_info monitor_info = { 0, 0, 0, 0 };
static struct strobe_cb_info monitor_info = { 0, 0, 0, 0, 0 };
static int monitor_scheduled = 0;
static vpiHandle *monitor_callbacks = 0;
@@ -420,6 +651,7 @@ static int sys_monitor_calltf(char*name)
array_from_iterator(&monitor_info, argv);
monitor_info.name = strdup(name);
monitor_info.default_format = get_default_format(name);
monitor_info.scope = scope;
monitor_callbacks = calloc(monitor_info.nitems, sizeof(vpiHandle));
@@ -550,12 +782,13 @@ static int sys_fdisplay_calltf(char *name)
mcd = value.value.integer;
assert(scope);
info.default_format = get_default_format(name);
info.scope = scope;
array_from_iterator(&info, argv);
do_display(mcd, &info);
free(info.items);
if (strcmp(name,"$fdisplay") == 0)
if (strncmp(name,"$fdisplay",9) == 0)
vpi_mcd_printf(mcd, "\n");
return 0;
@@ -674,6 +907,7 @@ void sys_display_register()
{
s_vpi_systf_data tf_data;
//============================== display
tf_data.type = vpiSysTask;
tf_data.tfname = "$display";
tf_data.calltf = sys_display_calltf;
@@ -682,6 +916,31 @@ void sys_display_register()
tf_data.user_data = "$display";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$displayh";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$displayh";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$displayo";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$displayo";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$displayb";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$displayb";
vpi_register_systf(&tf_data);
//============================== write
tf_data.type = vpiSysTask;
tf_data.tfname = "$write";
tf_data.calltf = sys_display_calltf;
@@ -690,6 +949,31 @@ void sys_display_register()
tf_data.user_data = "$write";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$writeh";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$writeh";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$writeo";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$writeo";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$writeb";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$writeb";
vpi_register_systf(&tf_data);
//============================== strobe
tf_data.type = vpiSysTask;
tf_data.tfname = "$strobe";
tf_data.calltf = sys_strobe_calltf;
@@ -698,6 +982,31 @@ void sys_display_register()
tf_data.user_data = "$strobe";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$strobeh";
tf_data.calltf = sys_strobe_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$strobeh";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$strobeo";
tf_data.calltf = sys_strobe_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$strobeo";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$strobeb";
tf_data.calltf = sys_strobe_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$strobeb";
vpi_register_systf(&tf_data);
//============================== monitor
tf_data.type = vpiSysTask;
tf_data.tfname = "$monitor";
tf_data.calltf = sys_monitor_calltf;
@@ -706,6 +1015,31 @@ void sys_display_register()
tf_data.user_data = "$monitor";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$monitorh";
tf_data.calltf = sys_monitor_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$monitorh";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$monitoro";
tf_data.calltf = sys_monitor_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$monitoro";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$monitorb";
tf_data.calltf = sys_monitor_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$monitorb";
vpi_register_systf(&tf_data);
//============================== fopen
tf_data.type = vpiSysFunc;
tf_data.tfname = "$fopen";
tf_data.calltf = sys_fopen_calltf;
@@ -714,6 +1048,7 @@ void sys_display_register()
tf_data.user_data = "$fopen";
vpi_register_systf(&tf_data);
//============================== fclose
tf_data.type = vpiSysTask;
tf_data.tfname = "$fclose";
tf_data.calltf = sys_fclose_calltf;
@@ -722,6 +1057,7 @@ void sys_display_register()
tf_data.user_data = "$fclose";
vpi_register_systf(&tf_data);
//============================== fdisplay
tf_data.type = vpiSysTask;
tf_data.tfname = "$fdisplay";
tf_data.calltf = sys_fdisplay_calltf;
@@ -730,6 +1066,31 @@ void sys_display_register()
tf_data.user_data = "$fdisplay";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fdisplayh";
tf_data.calltf = sys_fdisplay_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fdisplayh";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fdisplayo";
tf_data.calltf = sys_fdisplay_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fdisplayo";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fdisplayb";
tf_data.calltf = sys_fdisplay_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fdisplayb";
vpi_register_systf(&tf_data);
//============================== fwrite
tf_data.type = vpiSysTask;
tf_data.tfname = "$fwrite";
tf_data.calltf = sys_fdisplay_calltf;
@@ -738,6 +1099,7 @@ void sys_display_register()
tf_data.user_data = "$fwrite";
vpi_register_systf(&tf_data);
//============================== fputc
tf_data.type = vpiSysTask;
tf_data.tfname = "$fputc";
tf_data.calltf = sys_fputc_calltf;
@@ -746,6 +1108,7 @@ void sys_display_register()
tf_data.user_data = "$fputc";
vpi_register_systf(&tf_data);
//============================== fgetc
tf_data.type = vpiSysFunc;
tf_data.tfname = "$fgetc";
tf_data.calltf = sys_fgetc_calltf;
@@ -758,6 +1121,17 @@ void sys_display_register()
/*
* $Log: sys_display.c,v $
* Revision 1.34 2002/01/22 00:18:10 steve
* Better calcuation of dec string width (Larry Doolittle)
*
* Revision 1.33 2002/01/15 03:23:34 steve
* Default widths pad out as per the standard,
* add $displayb/o/h et al., and some better
* error messages for incorrect formats.
*
* Revision 1.32 2002/01/11 04:48:01 steve
* Add the %c format, and some warning messages.
*
* Revision 1.31 2001/11/02 05:56:47 steve
* initialize scope for %m in $fdisplay.
*
+201 -40
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_readmem.c,v 1.8 2001/12/01 02:40:10 steve Exp $"
#ident "$Id: sys_readmem.c,v 1.9 2002/01/31 04:28:17 steve Exp $"
#endif
# include "config.h"
@@ -29,11 +29,45 @@
# include <assert.h>
# include "sys_readmem_lex.h"
static int check_integer_constant(char*name, vpiHandle handle)
{
if (vpi_get(vpiType, handle) != vpiConstant){
vpi_printf("ERROR: %s parameter must be a constant\n", name);
return 0;
}
switch(vpi_get(vpiConstType, handle)){
case vpiDecConst:
case vpiBinaryConst:
case vpiOctConst:
case vpiHexConst:
return 1;
break;
/* We rely on vpi_get_value for reals and strings to return a correct */
/* integer value when this is requested. So only a warning is generated. */
case vpiRealConst:
vpi_printf("Warning: real supplied to %s instead of integer.\n", name);
return 1;
break;
case vpiStringConst:
vpi_printf("Warning: string supplied to %s instead of integer.\n", name);
return 1;
break;
}
/* switch statement covers all possibilities. Code should never come here... */
assert(0);
return 0;
}
static int sys_readmem_calltf(char*name)
{
int code;
int wwid;
char*path;
char*mem_name;
FILE*file;
unsigned addr;
s_vpi_value value;
@@ -42,6 +76,28 @@ static int sys_readmem_calltf(char*name)
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle item = vpi_scan(argv);
vpiHandle mitem;
vpiHandle start_item;
vpiHandle stop_item;
vpiHandle left_range;
vpiHandle right_range;
vpiHandle word_index;
/* These are left and right hand side parameters in the
declaration of the memory. */
int left_addr, right_addr;
/* start_addr and stop_addr are the parameters given to $readmem in the
verilog code. When not specified, start_addr is equal to the lower of
the [left,right]_addr and stop_addr is equal to the higher of the
[left,right]_addr. */
int start_addr, stop_addr, addr_incr;
/* min_addr and max_addr are equal to start_addr and stop_addr if
start_addr<stop_addr or vice versa if not... */
int min_addr, max_addr;
/*======================================== Get parameters */
if (item == 0) {
vpi_printf("%s: file name parameter missing.\n", name);
@@ -55,7 +111,7 @@ static int sys_readmem_calltf(char*name)
}
if (vpi_get(vpiConstType, item) != vpiStringConst) {
vpi_printf("ERROR: %s parameter must be a constant\n", name);
vpi_printf("ERROR: %s parameter must be a string\n", name);
vpi_free_object(argv);
return 0;
}
@@ -64,7 +120,7 @@ static int sys_readmem_calltf(char*name)
vpi_get_value(item, &value);
path = strdup(value.value.str);
/* Get and check the second paramter. It must be a memory. */
/* Get and check the second parameter. It must be a memory. */
mitem = vpi_scan(argv);
if (mitem == 0) {
vpi_printf("%s: Missing memory parameter\n", name);
@@ -79,10 +135,40 @@ static int sys_readmem_calltf(char*name)
return 0;
}
/* XXXX remaining parameters not supported. */
vpi_free_object(argv);
mem_name = vpi_get_str(vpiFullName, mitem);
/* Open the data file. */
/* Get optional third parameter. It must be a constant. */
start_item = vpi_scan(argv);
if (start_item!=0){
if (check_integer_constant(name, start_item) == 0){
vpi_free_object(argv);
return 0;
}
/* Get optional forth parameter. It must be a constant. */
stop_item = vpi_scan(argv);
if (stop_item!=0){
if (check_integer_constant(name, stop_item) == 0){
vpi_free_object(argv);
return 0;
}
/* Check that ther is no 5th parameter */
if (vpi_scan(argv) != 0){
vpi_printf("ERROR: %s accepts maximum 4 parameters!\n", name );
vpi_free_object(argv);
return 0;
}
}
}
else{
stop_item = 0;
}
/*======================================== Process parameters */
/* Open the data file. */
file = fopen(path, "r");
if (file == 0) {
vpi_printf("%s: Unable to open %s for reading.\n", name, path);
@@ -90,56 +176,128 @@ static int sys_readmem_calltf(char*name)
return 0;
}
/* Get left addr of memory */
left_range = vpi_handle(vpiLeftRange, mitem);
value.format = vpiIntVal;
vpi_get_value(left_range, &value);
left_addr = value.value.integer;
/* Get right addr of memory */
right_range = vpi_handle(vpiRightRange, mitem);
value.format = vpiIntVal;
vpi_get_value(right_range, &value);
right_addr = value.value.integer;
/* Get start_addr, stop_addr and addr_incr */
if (start_item==0){
start_addr = left_addr<right_addr ? left_addr : right_addr;
stop_addr = left_addr<right_addr ? right_addr : left_addr;
addr_incr = 1;
}
else{
s_vpi_value value;
value.format = vpiIntVal;
vpi_get_value(start_item, &value);
start_addr = value.value.integer;
if (stop_item==0){
stop_addr = left_addr<right_addr ? right_addr : left_addr;
addr_incr = 1;
}
else{
s_vpi_value value;
value.format = vpiIntVal;
vpi_get_value(stop_item, &value);
stop_addr = value.value.integer;
addr_incr = start_addr<stop_addr ? 1 : -1;
}
}
min_addr = start_addr<stop_addr ? start_addr : stop_addr ;
max_addr = start_addr<stop_addr ? stop_addr : start_addr;
/* Check that start_addr and stop_addr are within the memory
range */
if (left_addr<right_addr){
if (start_addr<left_addr || start_addr > right_addr) {
vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
return 0;
}
if (stop_addr<left_addr || stop_addr > right_addr) {
vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
return 0;
}
}
else{
if (start_addr<right_addr || start_addr > left_addr) {
vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
return 0;
}
if (stop_addr<right_addr || stop_addr > left_addr) {
vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
return 0;
}
}
words = vpi_iterate(vpiMemoryWord, mitem);
assert(words);
item = vpi_scan(words);
wwid = vpi_get(vpiSize, item);
/* variable that will be uses by the lexer to pass values
back to this code */
value.format = vpiVectorVal;
value.value.vector = calloc((wwid+31)/32, sizeof (s_vpi_vecval));
value.value.vector = calloc((wwid+31)/32, sizeof(s_vpi_vecval));
/* Configure the readmem lexer */
if (strcmp(name,"$readmemb") == 0)
sys_readmem_start_file(file, 1, wwid, value.value.vector);
else
sys_readmem_start_file(file, 0, wwid, value.value.vector);
addr = 0;
/*======================================== Read memory file */
/* Run through the input file and store the new contents in the memory */
addr = start_addr;
while ((code = readmemlex()) != 0) {
switch (code) {
case MEM_ADDRESS:
if (addr > value.value.vector->aval) {
vpi_free_object(words);
words = vpi_iterate(vpiMemoryWord, mitem);
item = vpi_scan(words);
addr = 0;
}
while (item && addr < value.value.vector->aval) {
item = vpi_scan(words);
addr += 1;
}
break;
case MEM_WORD:
if (item) {
vpi_put_value(item, &value, 0, vpiNoDelay);
item = vpi_scan(words);
addr += 1;
} else {
vpi_printf("%s(%s): too much data (addr=0x%x)\n",
name, path, addr);
goto bailout;
}
break;
default:
vpi_printf("Huh?! (%d)\n", code);
break;
}
switch (code) {
case MEM_ADDRESS:
addr = value.value.vector->aval;
break;
case MEM_WORD:
if (addr >= min_addr && addr <= max_addr){
word_index = vpi_handle_by_index(mitem, addr);
assert(word_index);
vpi_put_value(word_index, &value, 0, vpiNoDelay);
}
else{
vpi_printf("%s(%s): address (0x%x) out of range (0x%x:0x%x)\n",
name, path, addr, start_addr, stop_addr);
goto bailout;
}
addr += addr_incr;
break;
default:
vpi_printf("Huh?! (%d)\n", code);
break;
}
}
bailout:
if (item) vpi_free_object(words);
free(path);
bailout:
free(value.value.vector);
if (item)
vpi_free_object(words);
free(path);
fclose(file);
return 0;
}
@@ -177,7 +335,7 @@ static int sys_writemem_calltf(char*name)
vpi_get_value(item, &value);
path = strdup(value.value.str);
/* Get and check the second paramter. It must be a memory. */
/* Get and check the second parameter. It must be a memory. */
item = vpi_scan(argv);
if (item == 0) {
vpi_printf("%s: Missing memory parameter\n", name);
@@ -253,6 +411,9 @@ void sys_readmem_register()
/*
* $Log: sys_readmem.c,v $
* Revision 1.9 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.8 2001/12/01 02:40:10 steve
* Support addresses in readmemh.
*
+16 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_time.c,v 1.2 2001/07/25 03:10:50 steve Exp $"
#ident "$Id: sys_time.c,v 1.3 2002/01/11 05:20:59 steve Exp $"
#endif
# include "config.h"
@@ -30,6 +30,11 @@ static int sys_time_sizetf(char*x)
return 64;
}
static int sys_stime_sizetf(char*x)
{
return 32;
}
static int sys_time_calltf(char*name)
{
s_vpi_value val;
@@ -60,10 +65,20 @@ void sys_time_register()
tf_data.compiletf = 0;
tf_data.sizetf = sys_time_sizetf;
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$stime";
tf_data.calltf = sys_time_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = sys_stime_sizetf;
vpi_register_systf(&tf_data);
}
/*
* $Log: sys_time.c,v $
* Revision 1.3 2002/01/11 05:20:59 steve
* Add the stime system function.
*
* Revision 1.2 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+6 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vpi_user.h,v 1.6 2001/09/30 05:18:46 steve Exp $"
#ident "$Id: vpi_user.h,v 1.7 2002/01/24 04:19:39 steve Exp $"
#endif
@@ -157,6 +157,8 @@ typedef struct t_vpi_value {
#define vpiSysTaskCall 57
#define vpiTask 59
#define vpiTimeVar 63
#define vpiLeftRange 79
#define vpiRightRange 83
#define vpiScope 84
#define vpiSysTfCall 85
#define vpiArgument 89
@@ -309,6 +311,9 @@ EXTERN_C_END
/*
* $Log: vpi_user.h,v $
* Revision 1.7 2002/01/24 04:19:39 steve
* Add the vpiLeft.. and vpiRightRange constants
*
* Revision 1.6 2001/09/30 05:18:46 steve
* Reduce VCD output by removing duplicates. (Stephan Boettcher)
*
+15 -10
View File
@@ -7,30 +7,35 @@ static p_vpi_thunk vpi_thunk_p = 0;
#define VPITV_CALL(fn,args) { \
if (vpi_thunk_p == 0) { \
fprintf(stderr, "No Simulator registered, cannot handle vpi " \
"call to " #fn "\n"); \
return; \
no_sim(#fn); return; \
} \
if (vpi_thunk_p->fn == 0) { \
fprintf(stderr, "Simulator doesn't have a " #fn " function\n"); \
return; \
no_func(#fn); return; \
} \
vpi_thunk_p->fn args; \
}
#define VPIT_CALL(fn,def,args) { \
if (vpi_thunk_p == 0) { \
fprintf(stderr, "No Simulator registered, cannot handle vpi " \
"call to " #fn "\n"); \
return def; \
no_sim(#fn); return def; \
} \
if (vpi_thunk_p->fn == 0) { \
fprintf(stderr, "Simulator doesn't have a " #fn " function\n"); \
return; \
no_func(#fn); return def; \
} \
return vpi_thunk_p->fn args; \
}
static void no_sim(const char *fn)
{
fprintf(stderr, "No Simulator registered, cannot handle vpi "
"call to %s\n", fn);
}
static void no_func(const char *fn)
{
fprintf(stderr, "Simulator doesn't have a %s function\n",fn);
}
DLLEXPORT int vpi_register_sim(p_vpi_thunk tp)
{
vpi_thunk_p = 0;
+5 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_dlfcn.h,v 1.3 2001/05/22 02:14:47 steve Exp $"
#ident "$Id: ivl_dlfcn.h,v 1.4 2002/01/23 04:54:38 steve Exp $"
#endif
#if defined(__MINGW32__)
@@ -49,7 +49,7 @@ inline const char *dlerror(void)
#elif defined(HAVE_DLFCN_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_NOW); }
{ return dlopen(name,RTLD_LAZY); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{ return dlsym(dll, nm); }
@@ -77,6 +77,9 @@ inline const char*dlerror(void)
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.4 2002/01/23 04:54:38 steve
* Load modules with RTLD_LAZY
*
* Revision 1.3 2001/05/22 02:14:47 steve
* Update the mingw build to not require cygwin files.
*
+7 -5
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.32 2001/11/10 18:07:11 steve Exp $"
#ident "$Id: Makefile.in,v 1.35 2002/02/03 01:01:51 steve Exp $"
#
#
SHELL = /bin/sh
@@ -39,6 +39,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ -DMODULE_DIR=\"$(libdir)/ivl\"
CXXFLAGS = @CXXFLAGS@
@@ -61,7 +63,7 @@ check: all
V = vpi_modules.o vpi_callback.o vpi_const.o vpi_iter.o vpi_mcd.o \
vpi_priv.o vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
vpi_vthr_vector.o vvp_vpi.o
vpi_vthr_vector.o vpip_to_dec.o vvp_vpi.o
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
functor.o fvectors.o npmos.o resolv.o symbols.o codes.o vthread.o schedule.o \
@@ -88,11 +90,11 @@ parse.o: parse.cc
tables.o: tables.cc
parse.h parse.cc: $(srcdir)/parse.y
bison --verbose -t -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h
$(YACC) --verbose -t -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h || mv parse.hh parse.h
lexor.cc: $(srcdir)/lexor.lex
flex -s -olexor.cc $(srcdir)/lexor.lex
$(LEX) -s -olexor.cc $(srcdir)/lexor.lex
vvp.pdf: $(srcdir)/vvp.man
man -t $(srcdir)/vvp.man | ps2pdf - vvp.pdf
+2 -1
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* $Id: README.txt,v 1.38 2001/11/01 03:00:19 steve Exp $
* $Id: README.txt,v 1.39 2002/01/03 04:19:01 steve Exp $
*/
VVP SIMULATION ENGINE
@@ -433,6 +433,7 @@ create special statement types for the various arithmetic operators.
<label> .arith/sum <wid>, <symbols_list>;
<label> .arith/mult <wid>, <symbols_list>;
<label> .arith/div <wid>, <symbols_list>;
<label> .arith/mod <wid>, <symbols_list>;
Addition is represented by the .arith/sum statement. This creates an
array of functors based at the label. The width of the array is given
+45 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: arith.cc,v 1.21 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: arith.cc,v 1.22 2002/01/03 04:19:02 steve Exp $"
#endif
# include "arith.h"
@@ -128,6 +128,47 @@ void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
output_val_(base, push, a/b);
}
inline void vvp_arith_mod::wide(vvp_ipoint_t base, bool push)
{
assert(0);
}
void vvp_arith_mod::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
{
put(i, val);
vvp_ipoint_t base = ipoint_make(i,0);
if(wid_ > 8*sizeof(unsigned long)) {
wide(base, push);
return;
}
unsigned long a = 0, b = 0;
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base,idx);
functor_t obj = functor_index(ptr);
unsigned val = obj->ival;
if (val & 0xaa) {
output_x_(base, push);
return;
}
if (val & 0x01)
a += 1 << idx;
if (val & 0x04)
b += 1 << idx;
}
if (b == 0) {
output_x_(base, push);
return;
}
output_val_(base, push, a%b);
}
// Multiplication
void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
@@ -508,6 +549,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
/*
* $Log: arith.cc,v $
* Revision 1.22 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.21 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+13 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: arith.h,v 1.11 2001/10/31 04:27:46 steve Exp $"
#ident "$Id: arith.h,v 1.12 2002/01/03 04:19:02 steve Exp $"
#endif
# include "functor.h"
@@ -75,6 +75,15 @@ class vvp_arith_div : public vvp_arith_ {
void wide(vvp_ipoint_t base, bool push);
};
class vvp_arith_mod : public vvp_arith_ {
public:
explicit vvp_arith_mod(unsigned wid) : vvp_arith_(wid) {}
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
void wide(vvp_ipoint_t base, bool push);
};
class vvp_arith_sum : public vvp_wide_arith_ {
public:
@@ -125,6 +134,9 @@ class vvp_shiftr : public vvp_arith_ {
/*
* $Log: arith.h,v $
* Revision 1.12 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.11 2001/10/31 04:27:46 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+20 -8
View File
@@ -17,14 +17,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: bufif.cc,v 1.4 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: bufif.cc,v 1.6 2001/12/19 23:43:03 steve Exp $"
#endif
# include "bufif.h"
# include "functor.h"
# include "schedule.h"
void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
void vvp_bufif_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
{
put(ptr, v);
@@ -33,17 +33,17 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
unsigned char out0 = 0x00 | (odrive0<<0) | (odrive0<<4);
unsigned char out1 = 0x88 | (odrive1<<0) | (odrive1<<4);
unsigned char outX = 0x80 | (odrive1<<0) | (odrive0<<4);
unsigned char outX = 0x80 | (odrive0<<0) | (odrive1<<4);
unsigned char outH = 0x88 | (0) | (odrive1<<4);
unsigned char outL = 0x00 | (odrive1<<0) | (0);
unsigned char outL = 0x00 | (odrive0<<0) | (0);
unsigned val;
unsigned str;
switch (in1 ^ pol) {
switch (in1 ^ pol_) {
case 1:
switch (in0) {
switch (in0 ^ inv_) {
case 0:
val = 0;
str = out0;
@@ -64,16 +64,22 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
str = HiZ;
break;
/* The control input is x or z, so the output is H or
L, depending on the (possibly inverted) input. This
is not the same as X, as it is a combination of the
drive strength of the output and HiZ. */
default:
val = 2;
switch (in0) {
switch (in0 ^ inv_) {
case 0:
val = 2;
str = outL;
break;
case 1:
val = 2;
str = outH;
break;
default:
val = 2;
str = outX;
break;
}
@@ -85,6 +91,12 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
/*
* $Log: bufif.cc,v $
* Revision 1.6 2001/12/19 23:43:03 steve
* clarify bufif output strenghts.
*
* Revision 1.5 2001/12/14 06:03:17 steve
* Arrange bufif to support notif as well.
*
* Revision 1.4 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+11 -10
View File
@@ -19,28 +19,29 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: bufif.h,v 1.2 2001/10/31 04:27:46 steve Exp $"
#ident "$Id: bufif.h,v 1.3 2001/12/14 06:03:17 steve Exp $"
#endif
# include "functor.h"
class vvp_bufif1_s : public functor_s {
class vvp_bufif_s : public functor_s {
public:
vvp_bufif1_s() : pol(0) {}
vvp_bufif_s(bool en_invert, bool out_invert)
: pol_(en_invert? 1 : 0), inv_(out_invert? 1 : 0) {}
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
protected:
unsigned pol : 1;
};
class vvp_bufif0_s : public vvp_bufif1_s {
public:
vvp_bufif0_s() { pol = 1; }
private:
unsigned pol_ : 1;
unsigned inv_ : 1;
};
/*
* $Log: bufif.h,v $
* Revision 1.3 2001/12/14 06:03:17 steve
* Arrange bufif to support notif as well.
*
* Revision 1.2 2001/10/31 04:27:46 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+53 -94
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: compile.cc,v 1.115 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: compile.cc,v 1.120 2002/01/11 05:21:47 steve Exp $"
#endif
# include "arith.h"
@@ -481,7 +481,8 @@ void compile_vpi_symbol(const char*label, vpiHandle obj)
void compile_init(void)
{
sym_vpi = new_symbol_table();
compile_vpi_symbol("$time", vpip_sim_time());
compile_vpi_symbol("$time", vpip_sim_time());
compile_vpi_symbol("$stime", vpip_sim_time());
sym_functors = new_symbol_table();
functor_init();
@@ -529,6 +530,9 @@ void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
if (strcmp(argv[idx].text, "C<0>") == 0)
iobj->set(ifdx, false, 0, St0);
else if (strcmp(argv[idx].text, "C<we0>") == 0)
iobj->set(ifdx, false, 0, We0);
else if (strcmp(argv[idx].text, "C<pu0>") == 0)
iobj->set(ifdx, false, 0, Pu0);
@@ -538,6 +542,9 @@ void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
else if (strcmp(argv[idx].text, "C<1>") == 0)
iobj->set(ifdx, false, 1, St1);
else if (strcmp(argv[idx].text, "C<we1>") == 0)
iobj->set(ifdx, false, 1, We1);
else if (strcmp(argv[idx].text, "C<pu1>") == 0)
iobj->set(ifdx, false, 1, Pu1);
@@ -600,6 +607,9 @@ static void functor_reference(vvp_ipoint_t *ref, char *lab, unsigned idx)
else if (strcmp(lab, "C<pu0>") == 0)
*ref = make_const_functor(0,5,5);
else if (strcmp(lab, "C<we0>") == 0)
*ref = make_const_functor(0,3,3);
else if (strcmp(lab, "C<1>") == 0)
*ref = make_const_functor(1,6,6);
@@ -609,6 +619,9 @@ static void functor_reference(vvp_ipoint_t *ref, char *lab, unsigned idx)
else if (strcmp(lab, "C<pu1>") == 0)
*ref = make_const_functor(1,5,5);
else if (strcmp(lab, "C<we1>") == 0)
*ref = make_const_functor(1,3,3);
else if (strcmp(lab, "C<x>") == 0)
*ref = make_const_functor(2,6,6);
@@ -679,6 +692,22 @@ void compile_arith_div(char*label, long wid,
make_arith(arith, label, wid, argc, argv);
}
void compile_arith_mod(char*label, long wid,
unsigned argc, struct symb_s*argv)
{
assert( wid > 0 );
if ((long)argc != 2*wid) {
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
compile_errors += 1;
return;
}
vvp_arith_ *arith = new vvp_arith_mod(wid);
make_arith(arith, label, wid, argc, argv);
}
void compile_arith_mult(char*label, long wid,
unsigned argc, struct symb_s*argv)
{
@@ -858,7 +887,13 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
functor_t obj = 0;
if (strcmp(type,"tri") == 0) {
obj = new resolv_functor_s;
obj = new resolv_functor_s(HiZ);
} else if (strcmp(type,"tri0") == 0) {
obj = new resolv_functor_s(Pu0);
} else if (strcmp(type,"tri1") == 0) {
obj = new resolv_functor_s(Pu1);
} else {
fprintf(stderr, "invalid resolver type: %s\n", type);
@@ -1344,6 +1379,21 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
/*
* $Log: compile.cc,v $
* Revision 1.120 2002/01/11 05:21:47 steve
* Magic stime object support.
*
* Revision 1.119 2002/01/06 03:15:13 steve
* Support weak functor inputs.
*
* Revision 1.118 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.117 2001/12/15 02:11:51 steve
* Give tri0 and tri1 their proper strengths.
*
* Revision 1.116 2001/12/15 01:54:38 steve
* Support tri0 and tri1 resolvers.
*
* Revision 1.115 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
@@ -1370,96 +1420,5 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
*
* Revision 1.108 2001/10/16 02:47:37 steve
* Add arith/div object.
*
* Revision 1.107 2001/10/16 01:26:54 steve
* Add %div support (Anthony Bybell)
*
* Revision 1.106 2001/10/14 03:41:58 steve
* Handle mode-42 functor init.
*
* Revision 1.105 2001/10/12 03:00:08 steve
* M42 implementation of mode 2 (Stephan Boettcher)
*
* Revision 1.104 2001/10/12 02:53:47 steve
* functor lookup includes vpi signal search.
*
* Revision 1.103 2001/10/11 18:29:21 steve
* Propagate initial value of UDP.
*
* Revision 1.102 2001/10/09 16:57:47 steve
* Collect functor reference handling into a single function. (Stephan Boettcher)
*
* Revision 1.101 2001/10/09 02:28:16 steve
* Add the PMOS and NMOS functor types.
*
* Revision 1.100 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.99 2001/09/11 01:54:58 steve
* initial structural memory propagation (Stephan Boettcher)
*
* Revision 1.98 2001/08/26 22:59:32 steve
* Add the assign/x0 and set/x opcodes.
*
* Revision 1.97 2001/08/25 17:22:32 steve
* Only use fvectors for nets and vars.
*
* Revision 1.96 2001/08/10 04:31:09 steve
* Neaten and document the resolv object.
*
* Revision 1.95 2001/08/10 00:50:50 steve
* Make sure arithmetic objects run at time 0.
*
* Revision 1.94 2001/08/09 19:38:23 steve
* Nets (wires) do not use their own functors.
* Modifications to propagation of values.
* (Stephan Boettcher)
*
* Revision 1.93 2001/08/08 01:05:06 steve
* Initial implementation of vvp_fvectors.
* (Stephan Boettcher)
*
* Revision 1.92 2001/07/30 03:53:01 steve
* Initialize initial functor tables.
*
* Revision 1.91 2001/07/28 03:12:39 steve
* Support C<su0> and C<su1> special symbols.
*
* Revision 1.90 2001/07/26 03:13:51 steve
* Make the -M flag add module search paths.
*
* Revision 1.89 2001/07/22 00:04:50 steve
* Add the load/x instruction for bit selects.
*
* Revision 1.88 2001/07/19 04:40:55 steve
* Add support for the delayx opcode.
*
* Revision 1.87 2001/07/11 04:43:57 steve
* support postpone of $systask parameters. (Stephan Boettcher)
*
* Revision 1.86 2001/07/07 02:57:33 steve
* Add the .shift/r functor.
*
* Revision 1.85 2001/07/06 05:02:43 steve
* Properly initialize unconnected shift inputs.
*
* Revision 1.84 2001/07/06 04:46:44 steve
* Add structural left shift (.shift/l)
*
* Revision 1.83 2001/06/30 23:03:16 steve
* support fast programming by only writing the bits
* that are listed in the input file.
*
* Revision 1.82 2001/06/30 21:07:26 steve
* Support non-const right shift (unsigned).
*
* Revision 1.81 2001/06/23 18:26:26 steve
* Add the %shiftl/i0 instruction.
*
* Revision 1.80 2001/06/23 01:04:07 steve
* Allow forward references of task scopes. (Stephan Boettcher)
*
* Revision 1.79 2001/06/19 03:01:10 steve
* Add structural EEQ gates (Stephan Boettcher)
*/
+11 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: compile.h,v 1.38 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: compile.h,v 1.40 2002/01/03 04:19:02 steve Exp $"
#endif
# include <stdio.h>
@@ -73,7 +73,8 @@ extern void compile_vpi_time_precision(long pre);
* to existing functors to manage the linking.
*/
extern void compile_functor(char*label, char*type,
vvp_delay_t delay,
vvp_delay_t delay, unsigned ostr0,
unsigned ostr1,
unsigned argc, struct symb_s*argv);
@@ -96,6 +97,8 @@ extern void compile_force(char*label, struct symb_s signal,
*/
extern void compile_arith_div(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_arith_mod(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_arith_mult(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_arith_sum(char*label, long width,
@@ -222,6 +225,12 @@ extern void compile_net(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.40 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.39 2001/12/14 02:04:49 steve
* Support strength syntax on functors.
*
* Revision 1.38 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+16
View File
@@ -10,6 +10,22 @@ AC_EXEEXT
AC_MINGW32
AC_SUBST(EXEEXT)
AC_CHECK_PROGS(LEX,flex,none)
if test "$LEX" = "none"
then
echo "*** Error: No suitable flex found. ***"
echo " Please install the 'flex' package."
exit 1
fi
AC_CHECK_PROGS(YACC,bison,none)
if test "$YACC" = "none"
then
echo "*** Error: No suitable bison found. ***"
echo " Please install the 'bison' package."
exit 1
fi
AC_PROG_INSTALL
AC_ARG_ENABLE(vvp-debug, vvp-debug -- interactive debugger for VVP runtime.,
+6 -11
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: debug.cc,v 1.7 2001/09/15 18:27:05 steve Exp $"
#ident "$Id: debug.cc,v 1.8 2001/12/18 05:32:11 steve Exp $"
#endif
/*
@@ -71,7 +71,7 @@ static void cmd_fbreak(unsigned argc, char*argv[])
continue;
}
fp->breakpoint = 1;
fp->break_flag = 1;
}
}
@@ -92,15 +92,7 @@ static void cmd_functor(unsigned argc, char*argv[])
continue;
}
printf("0x%x: out pointer = 0x%x\n", fnc, fp->out);
printf("0x%x: input values = %c (%02x) %c (%02x)"
" %c (%02x) %c (%02x)\n", fnc,
bitval_tab[fp->ival&3], fp->istr[0],
bitval_tab[(fp->ival>>2)&3], fp->istr[1],
bitval_tab[(fp->ival>>4)&3], fp->istr[2],
bitval_tab[(fp->ival>>6)&3], fp->istr[3]);
printf("0x%x: out value = %c (%02x)\n", fnc,
bitval_tab[fp->oval], fp->ostr);
fp->debug_print(fnc);
}
}
@@ -173,6 +165,9 @@ void breakpoint(void)
#endif
/*
* $Log: debug.cc,v $
* Revision 1.8 2001/12/18 05:32:11 steve
* Improved functor debug dumps.
*
* Revision 1.7 2001/09/15 18:27:05 steve
* Make configure detect malloc.h
*
+31 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: draw_tt.c,v 1.11 2001/11/06 03:07:22 steve Exp $"
#ident "$Id: draw_tt.c,v 1.12 2002/01/12 04:02:16 steve Exp $"
#endif
# include <stdio.h>
@@ -122,6 +122,32 @@ static void draw_BUF(void)
printf("};\n");
}
static void draw_BUFZ(void)
{
unsigned i0, i1, i2, i3;
printf("const unsigned char ft_BUFZ[64] = {");
for (i3 = 0 ; i3 < 4 ; i3 += 1)
for (i2 = 0 ; i2 < 4 ; i2 += 1) {
printf("\n ");
for (i1 = 0 ; i1 < 4 ; i1 += 1) {
unsigned idx = (i3 << 4) | (i2 << 2) | i1;
unsigned char byte = 0;
for (i0 = 0 ; i0 < 4 ; i0 += 1) {
unsigned val = i0;
byte |= val << (i0*2);
}
printf("0x%02x, ", byte);
}
}
printf("};\n");
}
static void draw_BUFIF0(void)
{
unsigned i0, i1, i2, i3;
@@ -599,6 +625,7 @@ main()
draw_BUF();
draw_BUFIF0();
draw_BUFIF1();
draw_BUFZ();
draw_PMOS();
draw_NMOS();
draw_MUXZ();
@@ -616,6 +643,9 @@ main()
/*
* $Log: draw_tt.c,v $
* Revision 1.12 2002/01/12 04:02:16 steve
* Support the BUFZ logic device.
*
* Revision 1.11 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*
+27 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: event.cc,v 1.2 2001/11/16 04:22:27 steve Exp $"
#ident "$Id: event.cc,v 1.4 2002/01/24 04:17:46 steve Exp $"
#endif
# include "event.h"
@@ -39,6 +39,10 @@ event_functor_s::event_functor_s(edge_t e)
event_functor_s::~event_functor_s()
{}
/*
* Receive a value into an event functor, whether an edge or event/or.
* Detect edges, if any, then schedule awakened threads.
*/
void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
{
old_ival = ival;
@@ -49,6 +53,10 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
bool edge_p = true;
/* If there is an edge detect lookup table, then use the
old input and new input to detect whether this is the
requested edge. If there is no edge table, then any
set is a match. */
if (edge) {
unsigned pp = ipoint_port(ptr);
@@ -60,14 +68,23 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
edge_p = ((edge>>val) & 1) != 0;
}
/* If we detect an edge, then schedule any threads that
are attached to this event, then propagate the
positive detect to the output.
Note that only other events (notably event/or
functors) can be connected to event outputs. */
if (edge_p) {
vthread_t tmp = threads;
threads = 0;
vthread_schedule_list(tmp);
if (out)
// only one output? Why not propagate?
schedule_assign(out, 0, 0);
if (out) {
functor_set(out, 0, St0, true);
}
// only one output? Why not propagate?
//schedule_assign(out, 0, 0);
}
}
}
@@ -131,6 +148,12 @@ void compile_event(char*label, char*type,
/*
* $Log: event.cc,v $
* Revision 1.4 2002/01/24 04:17:46 steve
* Spelling in comment.
*
* Revision 1.3 2001/12/29 23:59:06 steve
* push events through event/or lists.
*
* Revision 1.2 2001/11/16 04:22:27 steve
* include stdlib.h for portability.
*
+54 -83
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.35 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: functor.cc,v 1.38 2002/01/06 17:50:50 steve Exp $"
#endif
# include "functor.h"
@@ -47,7 +47,7 @@
functor_t **functor_list = 0x0;
static unsigned functor_count = 0;
static unsigned functors_allocated = 0;
static unsigned functor_chunk_count = 0;
/*
* This function initializes the functor address space by creating the
@@ -60,6 +60,11 @@ void functor_init(void)
functor_allocate(1);
}
unsigned functor_limit()
{
return functor_count;
}
/*
* Allocate normally is just a matter of incrementing the functor_count
* and returning a pointer to the next unallocated functor. However,
@@ -71,26 +76,27 @@ vvp_ipoint_t functor_allocate(unsigned wid)
vvp_ipoint_t idx = functor_count*4;
functor_count += wid;
if (functor_count > functors_allocated*functor_chunks) {
if (functor_count > functor_chunk_count*functor_chunk_size) {
// enlarge the list of chunks
unsigned fa = (functor_count + functor_chunks - 1)/functor_chunks;
unsigned fa = (functor_count + functor_chunk_size - 1)
/ functor_chunk_size;
functor_list = (functor_t **)
realloc(functor_list, fa*sizeof(functor_t*));
assert(functor_list);
// allocate the chunks of functor pointers.
while (fa > functors_allocated) {
while (fa > functor_chunk_count) {
functor_list[functors_allocated] = (functor_t *)
malloc(functor_chunks * sizeof(functor_t));
assert(functor_list[functors_allocated]);
functor_list[functor_chunk_count] = (functor_t *)
malloc(functor_chunk_size * sizeof(functor_t));
assert(functor_list[functor_chunk_count]);
memset(functor_list[functors_allocated],
0,
functor_chunks * sizeof(functor_t));
memset(functor_list[functor_chunk_count], 0,
functor_chunk_size * sizeof(functor_t));
functors_allocated += 1;
functor_chunk_count += 1;
}
}
@@ -99,8 +105,8 @@ vvp_ipoint_t functor_allocate(unsigned wid)
void functor_define(vvp_ipoint_t point, functor_t obj)
{
unsigned index1 = point/4/functor_chunks;
unsigned index2 = (point/4) % functor_chunks;
unsigned index1 = point/4/functor_chunk_size;
unsigned index2 = (point/4) % functor_chunk_size;
functor_list[index1][index2] = obj;
}
@@ -122,7 +128,7 @@ functor_s::functor_s()
cstr = StX;
inhibit = 0;
#if defined(WITH_DEBUG)
breakpoint = 0;
break_flag = 0;
#endif
}
@@ -169,8 +175,41 @@ void extra_inputs_functor_s::set(vvp_ipoint_t i, bool push,
edge_inputs_functor_s::~edge_inputs_functor_s()
{}
#ifdef WITH_DEBUG
# include <stdio.h>
static const char bitval_tab[4] = { '0', '1', 'x', 'z' };
void functor_s::debug_print(vvp_ipoint_t fnc)
{
printf("0x%x: out pointer =", fnc);
vvp_ipoint_t cur = out;
while (cur) {
printf(" 0x%x", cur);
functor_t tmp = functor_index(cur);
cur = tmp->port[cur&3];
}
printf("\n");
printf("0x%x: input values = %c %c %c %c\n", fnc,
bitval_tab[ival&3],
bitval_tab[(ival>>2)&3],
bitval_tab[(ival>>4)&3],
bitval_tab[(ival>>6)&3]);
printf("0x%x: out value = %c (%02x)\n", fnc,
bitval_tab[get_oval()], get_ostr());
}
#endif
/*
* $Log: functor.cc,v $
* Revision 1.38 2002/01/06 17:50:50 steve
* Support scope for functors. (Stephan Boettcher)
*
* Revision 1.37 2001/12/18 05:32:11 steve
* Improved functor debug dumps.
*
* Revision 1.36 2001/12/14 01:59:28 steve
* Better variable names for functor chunks.
*
* Revision 1.35 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
@@ -197,73 +236,5 @@ edge_inputs_functor_s::~edge_inputs_functor_s()
*
* Revision 1.28 2001/10/27 03:43:56 steve
* Propagate functor push, to make assign better.
*
* Revision 1.27 2001/10/12 03:00:09 steve
* M42 implementation of mode 2 (Stephan Boettcher)
*
* Revision 1.26 2001/08/08 01:05:06 steve
* Initial implementation of vvp_fvectors.
* (Stephan Boettcher)
*
* Revision 1.25 2001/07/30 03:53:01 steve
* Initialize initial functor tables.
*
* Revision 1.24 2001/07/16 18:06:01 steve
* Initialize allocated functors (Stephan Boettcher)
*
* Revision 1.23 2001/06/21 22:54:12 steve
* Support cbValueChange callbacks.
*
* Revision 1.22 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.21 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.20 2001/05/12 20:38:06 steve
* A resolver that understands some simple strengths.
*
* Revision 1.19 2001/05/09 04:23:18 steve
* Now that the interactive debugger exists,
* there is no use for the output dump.
*
* Revision 1.18 2001/05/09 02:53:25 steve
* Implement the .resolv syntax.
*
* Revision 1.17 2001/05/08 23:32:26 steve
* Add to the debugger the ability to view and
* break on functors.
*
* Add strengths to functors at compile time,
* and Make functors pass their strengths as they
* propagate their output.
*
* Revision 1.16 2001/05/06 03:51:37 steve
* Regularize the mode-42 functor handling.
*
* Revision 1.15 2001/05/03 04:54:33 steve
* Fix handling of a mode 1 functor that feeds into a
* mode 2 functor. Feed the result only if the event
* is triggered, and do pass to the output even if no
* threads are waiting.
*
* Revision 1.14 2001/04/26 15:52:22 steve
* Add the mode-42 functor concept to UDPs.
*
* Revision 1.13 2001/04/24 02:23:59 steve
* Support for UDP devices in VVP (Stephen Boettcher)
*
* Revision 1.12 2001/04/18 04:21:23 steve
* Put threads into scopes.
*
* Revision 1.11 2001/04/14 05:10:56 steve
* support the .event/or statement.
*
* Revision 1.10 2001/04/03 03:18:34 steve
* support functor_set push for blocking assignment.
*
* Revision 1.9 2001/03/31 19:29:23 steve
* Fix compilation warnings.
*/
+30 -7
View File
@@ -19,11 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.40 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: functor.h,v 1.44 2002/01/06 17:50:50 steve Exp $"
#endif
# include "pointers.h"
# include "delay.h"
#ifdef ENABLE_VVP_DEBUG
# include "debug.h"
#endif
/*
* The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits
@@ -88,9 +91,11 @@ enum strength_e {
Su0 = 0x77, /* Su0-Su0 */
St0 = 0x66, /* St0-St0 */
Pu0 = 0x55, /* Pu0-Pu0 */
We0 = 0x33, /* We0-We0 */
Su1 = 0x77|0x88, /* Su1 - Su1 */
St1 = 0x66|0x88, /* St1 - St1 */
Pu1 = 0x55|0x88, /* Pu1 - Pu1 */
We1 = 0x33|0x88, /* We1 - We1 */
StX = 0x66|0x80, /* St0 - St1 */
};
@@ -112,6 +117,11 @@ extern void functor_init(void);
*/
extern vvp_ipoint_t functor_allocate(unsigned wid);
/*
** Return the number of allocated functors
*/
extern unsigned functor_limit();
/*
* Given an ipoint_t pointer, return a C pointer to the functor. This
* is like a pointer dereference. The point parameter must have been
@@ -119,12 +129,12 @@ extern vvp_ipoint_t functor_allocate(unsigned wid);
*/
extern functor_t **functor_list;
static const unsigned functor_chunks = 0x400;
static const unsigned functor_chunk_size = 0x400;
inline static functor_t functor_index(vvp_ipoint_t point)
{
unsigned index1 = point/4/functor_chunks;
unsigned index2 = (point/4) % functor_chunks;
unsigned index1 = point/4/functor_chunk_size;
unsigned index2 = (point/4) % functor_chunk_size;
return functor_list[index1][index2];
}
@@ -174,7 +184,8 @@ struct functor_s {
public:
#if defined(WITH_DEBUG)
/* True if this functor triggers a breakpoint. */
unsigned breakpoint : 1;
unsigned break_flag : 1;
virtual void debug_print(vvp_ipoint_t fnc);
#endif
public:
@@ -220,7 +231,7 @@ inline void functor_s::propagate(unsigned val, unsigned str, bool push)
}
#if defined(WITH_DEBUG)
if (breakpoint)
if (break_flag)
breakpoint();
#endif
}
@@ -299,7 +310,7 @@ void functor_set(vvp_ipoint_t ptr, unsigned val, unsigned str, bool push = true)
fp->set(ptr, push, val, str);
#if defined(WITH_DEBUG)
if (fp->breakpoint)
if (fp->break_flag)
breakpoint();
#endif
}
@@ -375,6 +386,18 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
/*
* $Log: functor.h,v $
* Revision 1.44 2002/01/06 17:50:50 steve
* Support scope for functors. (Stephan Boettcher)
*
* Revision 1.43 2002/01/06 03:15:13 steve
* Support weak functor inputs.
*
* Revision 1.42 2001/12/18 05:32:11 steve
* Improved functor debug dumps.
*
* Revision 1.41 2001/12/14 01:59:28 steve
* Better variable names for functor chunks.
*
* Revision 1.40 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+5 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_dlfcn.h,v 1.3 2001/05/22 02:14:47 steve Exp $"
#ident "$Id: ivl_dlfcn.h,v 1.4 2002/01/23 04:54:38 steve Exp $"
#endif
#if defined(__MINGW32__)
@@ -49,7 +49,7 @@ inline const char *dlerror(void)
#elif defined(HAVE_DLFCN_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_NOW); }
{ return dlopen(name,RTLD_LAZY); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{ return dlsym(dll, nm); }
@@ -77,6 +77,9 @@ inline const char*dlerror(void)
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.4 2002/01/23 04:54:38 steve
* Load modules with RTLD_LAZY
*
* Revision 1.3 2001/05/22 02:14:47 steve
* Update the mingw build to not require cygwin files.
*
+5 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.28 2001/11/01 03:00:19 steve Exp $"
#ident "$Id: lexor.lex,v 1.29 2002/01/03 04:19:02 steve Exp $"
#endif
# include "parse_misc.h"
@@ -67,6 +67,7 @@
/* These are some keywords that are recognized. */
".arith/div" { return K_ARITH_DIV; }
".arith/mod" { return K_ARITH_MOD; }
".arith/mult" { return K_ARITH_MULT; }
".arith/sub" { return K_ARITH_SUB; }
".arith/sum" { return K_ARITH_SUM; }
@@ -150,6 +151,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.29 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.28 2001/11/01 03:00:19 steve
* Add force/cassign/release/deassign support. (Stephan Boettcher)
*
+38 -15
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: logic.cc,v 1.4 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: logic.cc,v 1.7 2002/01/12 04:02:16 steve Exp $"
#endif
# include "logic.h"
@@ -37,9 +37,14 @@
* to 4 inputs.
*/
inline table_functor_s::table_functor_s(truth_t t)
: table(t)
{}
table_functor_s::table_functor_s(truth_t t, unsigned str0, unsigned str1)
: table(t)
{
assert(str0 <= 7);
assert(str1 <= 7);
odrive0 = str0;
odrive1 = str1;
}
table_functor_s::~table_functor_s()
{}
@@ -63,25 +68,28 @@ void table_functor_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
*/
void compile_functor(char*label, char*type,
vvp_delay_t delay,
vvp_delay_t delay, unsigned ostr0, unsigned ostr1,
unsigned argc, struct symb_s*argv)
{
functor_t obj;
if (strcmp(type, "OR") == 0) {
obj = new table_functor_s(ft_OR);
obj = new table_functor_s(ft_OR, ostr0, ostr1);
} else if (strcmp(type, "AND") == 0) {
obj = new table_functor_s(ft_AND);
obj = new table_functor_s(ft_AND, ostr0, ostr1);
} else if (strcmp(type, "BUF") == 0) {
obj = new table_functor_s(ft_BUF);
obj = new table_functor_s(ft_BUF, ostr0, ostr1);
} else if (strcmp(type, "BUFIF0") == 0) {
obj = new vvp_bufif0_s;
obj = new vvp_bufif_s(true,false);
} else if (strcmp(type, "BUFIF1") == 0) {
obj = new vvp_bufif1_s;
obj = new vvp_bufif_s(false,false);
} else if (strcmp(type, "BUFZ") == 0) {
obj = new table_functor_s(ft_BUFZ, ostr0, ostr1);
} else if (strcmp(type, "PMOS") == 0) {
obj = new vvp_pmos_s;
@@ -102,19 +110,25 @@ void compile_functor(char*label, char*type,
obj = new table_functor_s(ft_EEQ);
} else if (strcmp(type, "NAND") == 0) {
obj = new table_functor_s(ft_NAND);
obj = new table_functor_s(ft_NAND, ostr0, ostr1);
} else if (strcmp(type, "NOR") == 0) {
obj = new table_functor_s(ft_NOR);
obj = new table_functor_s(ft_NOR, ostr0, ostr1);
} else if (strcmp(type, "NOT") == 0) {
obj = new table_functor_s(ft_NOT);
obj = new table_functor_s(ft_NOT, ostr0, ostr1);
} else if (strcmp(type, "NOTIF0") == 0) {
obj = new vvp_bufif_s(true,true);
} else if (strcmp(type, "NOTIF1") == 0) {
obj = new vvp_bufif_s(false,true);
} else if (strcmp(type, "XNOR") == 0) {
obj = new table_functor_s(ft_XNOR);
obj = new table_functor_s(ft_XNOR, ostr0, ostr1);
} else if (strcmp(type, "XOR") == 0) {
obj = new table_functor_s(ft_XOR);
obj = new table_functor_s(ft_XOR, ostr0, ostr1);
} else {
yyerror("invalid functor type.");
@@ -141,6 +155,15 @@ void compile_functor(char*label, char*type,
/*
* $Log: logic.cc,v $
* Revision 1.7 2002/01/12 04:02:16 steve
* Support the BUFZ logic device.
*
* Revision 1.6 2001/12/14 06:03:17 steve
* Arrange bufif to support notif as well.
*
* Revision 1.5 2001/12/14 02:04:49 steve
* Support strength syntax on functors.
*
* Revision 1.4 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+15 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: logic.h,v 1.1 2001/11/06 03:07:22 steve Exp $"
#ident "$Id: logic.h,v 1.3 2002/01/12 04:02:16 steve Exp $"
#endif
# include "functor.h"
@@ -28,11 +28,16 @@
* Table driven functor. oval = table[ival];
*/
struct table_functor_s: public functor_s {
class table_functor_s: public functor_s {
public:
typedef const unsigned char *truth_t;
explicit table_functor_s(truth_t t);
explicit table_functor_s(truth_t t, unsigned str0 =6, unsigned str1 =6);
virtual ~table_functor_s();
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
private:
truth_t table;
};
@@ -42,6 +47,7 @@ extern const unsigned char ft_AND[];
extern const unsigned char ft_BUF[];
extern const unsigned char ft_BUFIF0[];
extern const unsigned char ft_BUFIF1[];
extern const unsigned char ft_BUFZ[];
extern const unsigned char ft_PMOS[];
extern const unsigned char ft_NMOS[];
extern const unsigned char ft_MUXZ[];
@@ -56,6 +62,12 @@ extern const unsigned char ft_var[];
/*
* $Log: logic.h,v $
* Revision 1.3 2002/01/12 04:02:16 steve
* Support the BUFZ logic device.
*
* Revision 1.2 2001/12/14 02:04:49 steve
* Support strength syntax on functors.
*
* Revision 1.1 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*
+8 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: main.cc,v 1.21 2001/10/20 01:03:42 steve Exp $"
#ident "$Id: main.cc,v 1.22 2002/01/09 03:15:23 steve Exp $"
#endif
# include "config.h"
@@ -125,6 +125,7 @@ int main(int argc, char*argv[])
struct rusage cycles[3];
const char *logfile_name = 0x0;
FILE *logfile = 0x0;
extern void vpi_set_vlog_info(int, char**);
#ifdef __MINGW32__
/* In the Windows world, we get the first module path
@@ -206,9 +207,11 @@ int main(int argc, char*argv[])
}
vpi_mcd_init(logfile);
vvp_vpi_init();
vpi_set_vlog_info(argc, argv);
compile_init();
for (unsigned idx = 0 ; idx < module_cnt ; idx += 1)
@@ -256,6 +259,9 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.22 2002/01/09 03:15:23 steve
* Add vpi_get_vlog_info support.
*
* Revision 1.21 2001/10/20 01:03:42 steve
* Print memory usage information if requested (Stephan Boettcher)
*
+33 -1
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: memory.cc,v 1.14 2001/12/06 03:31:24 steve Exp $"
#ident "$Id: memory.cc,v 1.15 2002/01/31 04:28:17 steve Exp $"
#endif
#include "memory.h"
@@ -63,6 +63,10 @@ struct vvp_memory_index_s
{
int first; // first memory address
unsigned size; // number of valid addresses
// Added to correctly support vpiLeftRange and vpiRightRange
int left;
int right;
};
struct vvp_memory_port_s : public functor_s
@@ -95,6 +99,30 @@ unsigned memory_root(vvp_memory_t mem, unsigned ix)
return mem->a_idx[ix].first;
}
unsigned memory_left_range(vvp_memory_t mem, unsigned ix)
{
if (ix >= mem->a_idxs)
return 0;
return mem->a_idx[ix].left;
}
unsigned memory_right_range(vvp_memory_t mem, unsigned ix)
{
if (ix >= mem->a_idxs)
return 0;
return mem->a_idx[ix].right;
}
unsigned memory_word_left_range(vvp_memory_t mem)
{
return mem->msb;
}
unsigned memory_word_right_range(vvp_memory_t mem)
{
return mem->lsb;
}
char *memory_name(vvp_memory_t mem)
{
return mem->name;
@@ -146,6 +174,10 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb,
vvp_memory_index_t x = mem->a_idx + i;
int msw = *(idx++);
int lsw = *(idx++);
x->left = msw;
x->right = lsw;
if (msw > lsw) {
x->size = msw - lsw + 1;
x->first = lsw;
+8 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: memory.h,v 1.4 2001/10/31 04:27:47 steve Exp $"
#ident "$Id: memory.h,v 1.5 2002/01/31 04:28:17 steve Exp $"
#endif
#include "pointers.h"
@@ -52,6 +52,10 @@ unsigned memory_size(vvp_memory_t mem);
char *memory_name(vvp_memory_t mem);
unsigned memory_data_width(vvp_memory_t mem);
unsigned memory_root(vvp_memory_t mem, unsigned ix = 0);
unsigned memory_left_range(vvp_memory_t mem, unsigned ix = 0);
unsigned memory_right_range(vvp_memory_t mem, unsigned ix = 0);
unsigned memory_word_left_range(vvp_memory_t mem);
unsigned memory_word_right_range(vvp_memory_t mem);
/*
** Access to the memory symbol table.
@@ -61,6 +65,9 @@ vvp_memory_t memory_create(char *label);
/*
* $Log: memory.h,v $
* Revision 1.5 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.4 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+5 -1
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* $Id: opcodes.txt,v 1.31 2001/11/01 03:00:19 steve Exp $
* $Id: opcodes.txt,v 1.32 2002/01/26 02:08:07 steve Exp $
*/
@@ -379,6 +379,10 @@ This sets the bit of a variable functor, the address calculated by
using the index register <idx> (0, 1, 2 or 3) to index the functor
address of <var-label>.
If the index value in index register <idx> is <0 (for example if
%ix/get converted an unknown value into the register) then the set is
not performed.
* %shiftl/i0 <bit>, <wid>
+23 -6
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.41 2001/12/06 03:31:25 steve Exp $"
#ident "$Id: parse.y,v 1.43 2002/01/03 04:19:02 steve Exp $"
#endif
# include "parse_misc.h"
@@ -57,7 +57,8 @@ extern FILE*yyin;
};
%token K_ARITH_DIV K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM K_CMP_GE K_CMP_GT
%token K_ARITH_DIV K_ARITH_MOD K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM
%token K_CMP_GE K_CMP_GT
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD
%token K_UDP K_UDP_C K_UDP_S
@@ -119,13 +120,18 @@ program
statement
/* Functor statements define functors. The functor must have a
label and a type name, and may have operands. */
label and a type name, and may have operands. The functor may
also have a delay specification and output strengths. */
: T_LABEL K_FUNCTOR T_SYMBOL delay ',' symbols ';'
{ compile_functor($1, $3, $4, $6.cnt, $6.vect); }
{ compile_functor($1, $3, $4, 6, 6, $6.cnt, $6.vect); }
| T_LABEL K_FUNCTOR T_SYMBOL delay ',' T_NUMBER ';'
{ compile_functor($1, $3, $4, 0, 0); }
| T_LABEL K_FUNCTOR T_SYMBOL delay
'[' T_NUMBER T_NUMBER ']' ',' symbols ';'
{ unsigned str0 = $6;
unsigned str1 = $7;
compile_functor($1, $3, $4, str0, str1, $10.cnt, $10.vect);
}
/* UDP statements define or instantiate UDPs. Definitions take a
@@ -177,6 +183,11 @@ statement
compile_arith_div($1, $3, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_MOD T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_mod($1, $3, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_MULT T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_mult($1, $3, obj.cnt, obj.vect);
@@ -527,6 +538,12 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.43 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.42 2001/12/14 02:04:49 steve
* Support strength syntax on functors.
*
* Revision 1.41 2001/12/06 03:31:25 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+37 -2
View File
@@ -17,11 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: resolv.cc,v 1.9 2001/12/06 03:31:25 steve Exp $"
#ident "$Id: resolv.cc,v 1.12 2001/12/18 05:32:11 steve Exp $"
#endif
# include "resolv.h"
# include "schedule.h"
# include <assert.h>
/*
* A signal value is unambiguous if the top 4 bits and the bottom 4
@@ -132,6 +133,16 @@ static unsigned blend(unsigned a, unsigned b)
return res;
}
resolv_functor_s::resolv_functor_s(unsigned char pull)
{
istr[0]=istr[1]=istr[2]=istr[3]=StX;
hiz_ = pull;
}
resolv_functor_s::~resolv_functor_s()
{
}
/*
* Resolve the strength values of the inputs, two at a time. Pairs of
* inputs are resolved with the blend function, and the final value is
@@ -142,7 +153,8 @@ void resolv_functor_s::set(vvp_ipoint_t i, bool push, unsigned, unsigned str)
unsigned pp = ipoint_port(i);
istr[pp] = str;
unsigned sval = istr[0];
unsigned sval = hiz_;
sval = blend(sval, istr[0]);
sval = blend(sval, istr[1]);
sval = blend(sval, istr[2]);
sval = blend(sval, istr[3]);
@@ -173,8 +185,31 @@ void resolv_functor_s::set(vvp_ipoint_t i, bool push, unsigned, unsigned str)
put_ostr(val, sval, false);
}
#ifdef WITH_DEBUG
# include <stdio.h>
static const char bitval_tab[4] = { '0', '1', 'x', 'z' };
void resolv_functor_s::debug_print(vvp_ipoint_t fnc)
{
printf("0x%x: Resolver tied to %02x\n", fnc, hiz_);
printf("0x%x: input strengths = %02x %02x %02x %02x\n", fnc,
istr[0], istr[1], istr[2], istr[3]);
functor_s::debug_print(fnc);
}
#endif
/*
* $Log: resolv.cc,v $
* Revision 1.12 2001/12/18 05:32:11 steve
* Improved functor debug dumps.
*
* Revision 1.11 2001/12/15 02:11:51 steve
* Give tri0 and tri1 their proper strengths.
*
* Revision 1.10 2001/12/15 01:54:39 steve
* Support tri0 and tri1 resolvers.
*
* Revision 1.9 2001/12/06 03:31:25 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+27 -2
View File
@@ -19,21 +19,46 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: resolv.h,v 1.3 2001/10/31 04:27:47 steve Exp $"
#ident "$Id: resolv.h,v 1.6 2001/12/18 05:32:11 steve Exp $"
#endif
# include "config.h"
# include "functor.h"
/*
* This functor type resolves its inputs using the verilog method of
* combining signals, and outputs that resolved value. The puller
* value is also blended with the result. This helps with the
* implementation of tri0 and tri1, which have pull constants attached.
*/
class resolv_functor_s: public functor_s {
public:
resolv_functor_s() { istr[0]=istr[1]=istr[2]=istr[3]=StX; }
explicit resolv_functor_s(unsigned char hiz_value);
~resolv_functor_s();
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
#ifdef WITH_DEBUG
void debug_print(vvp_ipoint_t fnc);
#endif
private:
unsigned char istr[4];
unsigned char hiz_;
};
/*
* $Log: resolv.h,v $
* Revision 1.6 2001/12/18 05:32:11 steve
* Improved functor debug dumps.
*
* Revision 1.5 2001/12/15 02:11:51 steve
* Give tri0 and tri1 their proper strengths.
*
* Revision 1.4 2001/12/15 01:54:39 steve
* Support tri0 and tri1 resolvers.
*
* Revision 1.3 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+11 -5
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: udp.cc,v 1.14 2001/12/06 03:31:25 steve Exp $"
#ident "$Id: udp.cc,v 1.16 2002/01/20 23:27:51 steve Exp $"
#endif
#include "udp.h"
@@ -74,7 +74,7 @@ typedef unsigned int udp_vec_t;
struct udp_table_entry_s
{
udp_vec_t not_0; // all inputs that must not be 0
udp_vec_t not_1x; // all inputs that bust not be 1 or x
udp_vec_t not_1x; // all inputs that must not be 1, x
unsigned char edge_idx; // input index of the edge
unsigned char edge_type; // permissible transitions. 0: no edge.
unsigned char out; // new output, 0..2
@@ -129,9 +129,9 @@ unsigned char vvp_udp_s::propagate(functor_t fu, vvp_ipoint_t uix)
if (sequ)
{
if (edge_type == 0)
return fu->get();
return fu->get_oval();
invec <<= 2;
invec |= (fu->get() & 3);
invec |= (fu->get_oval() & 3);
}
udp_vec_t inx = invec & 0xaaaaaaaaU; // all 'x'/'z'
@@ -163,7 +163,7 @@ unsigned char vvp_udp_s::propagate(functor_t fu, vvp_ipoint_t uix)
}
if (ret>2)
ret = fu->get();
ret = fu->get_oval();
return ret;
}
@@ -350,6 +350,12 @@ void vvp_udp_s::compile_row_(udp_table_entry_t row, char *rchr)
/*
* $Log: udp.cc,v $
* Revision 1.16 2002/01/20 23:27:51 steve
* return calculated oval from UDP (Stephan Boettcher)
*
* Revision 1.15 2002/01/06 17:35:01 steve
* Feedback output, not propagated output. (Stephan Boettcher)
*
* Revision 1.14 2001/12/06 03:31:25 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
+220 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_const.cc,v 1.7 2001/09/15 18:27:05 steve Exp $"
#ident "$Id: vpi_const.cc,v 1.11 2002/02/03 01:01:51 steve Exp $"
#endif
# include "vpi_priv.h"
@@ -29,21 +29,40 @@
# include <string.h>
# include <assert.h>
static char buf[4096];
static int string_get(int code, vpiHandle ref)
{
struct __vpiStringConst*rfp;
switch (code) {
case vpiSize:
rfp = (struct __vpiStringConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
//fprintf(stderr, "String:|%s|, Length: %d\n", rfp->value, strlen(rfp->value));
return strlen(rfp->value)*8;
case vpiSigned:
return 0;
case vpiConstType:
return vpiStringConst;
return vpiStringConst;
default:
assert(0);
return 0;
fprintf(stderr, "vvp error: get %d not supported "
"by vpiStringConst\n", code);
assert(0);
return 0;
}
}
static void string_value(vpiHandle ref, p_vpi_value vp)
{
int size;
unsigned uint_value;
char *cp;
struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
@@ -54,7 +73,76 @@ static void string_value(vpiHandle ref, p_vpi_value vp)
vp->format = vpiStringVal;
break;
case vpiDecStrVal:
size = strlen(rfp->value);
if (size > 4){
// We only support standard integers. Ignore other bytes...
size = 4;
fprintf(stderr, "Warning (vpi_const.cc): %%d on constant strings only looks "
"at first 4 bytes!\n");
}
uint_value = 0;
for(int i=0; i<size;i ++){
uint_value <<=8;
uint_value += (unsigned char)(rfp->value[i]);
}
sprintf(buf, "%u", uint_value);
vp->format = vpiDecStrVal;
vp->value.str = buf;
break;
case vpiBinStrVal:
size = strlen(rfp->value);
if (size*8 > (int)(sizeof(buf)/sizeof(char))-1 ){
// Avoid overflow of 'buf'
// 4096 should be sufficient for most cases though. ;-)
size = (sizeof(buf)/sizeof(char)-2)/8;
}
cp = buf;
for(int i=0; i<size;i ++){
for(int bit=7;bit>=0; bit--){
*cp++ = "01"[ (rfp->value[i]>>bit)&1 ];
}
}
*cp = 0;
vp->format = vpiBinStrVal;
vp->value.str = buf;
break;
case vpiHexStrVal:
size = strlen(rfp->value);
if (size*2 > (int)(sizeof(buf)/sizeof(char))-1 ){
// Avoid overflow of 'buf'
// 4096 should be sufficient for most cases though. ;-)
size = (sizeof(buf)/sizeof(char)-2)/2;
}
cp = buf;
for(int i=0; i<size;i++){
for(int nibble=1;nibble>=0; nibble--){
*cp++ = "0123456789abcdef"[ (rfp->value[i]>>(nibble*4))&15 ];
}
}
*cp = 0;
vp->format = vpiHexStrVal;
vp->value.str = buf;
break;
case vpiOctStrVal:
fprintf(stderr, "ERROR (vpi_const.cc): %%o display of constant strings not yet implemented\n");
assert(0);
break;
default:
fprintf(stderr, "ERROR (vpi_const.cc): vp->format: %d\n", vp->format);
assert(0);
vp->format = vpiSuppressVal;
break;
}
@@ -87,18 +175,27 @@ vpiHandle vpip_make_string_const(char*text)
static int binary_get(int code, vpiHandle ref)
{
struct __vpiBinaryConst*rfp = (struct __vpiBinaryConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
switch (code) {
case vpiConstType:
return vpiBinaryConst;
case vpiSigned: // FIXME: Need to get signed flag right.
return 0;
case vpiSize:
return rfp->nbits;
default:
fprintf(stderr, "vvp error: get %d not supported "
"by vpiBinaryConst\n", code);
assert(0);
return 0;
}
}
static char buf[4096];
static void binary_value(vpiHandle ref, p_vpi_value vp)
{
@@ -109,6 +206,7 @@ static void binary_value(vpiHandle ref, p_vpi_value vp)
case vpiObjTypeVal:
case vpiBinStrVal:
assert(rfp->nbits < sizeof buf);
for (unsigned idx = 0 ; idx < rfp->nbits ; idx += 1) {
unsigned nibble = idx/4;
unsigned shift = 2 * (idx%4);
@@ -121,6 +219,14 @@ static void binary_value(vpiHandle ref, p_vpi_value vp)
vp->format = vpiBinStrVal;
break;
case vpiDecStrVal:
vpip_bits_to_dec_str(rfp->bits, rfp->nbits,
buf, sizeof buf, 0);
vp->value.str = buf;
vp->format = vpiDecStrVal;
break;
case vpiIntVal: {
unsigned val = 0;
@@ -195,8 +301,117 @@ vpiHandle vpip_make_binary_const(unsigned wid, char*bits)
}
static int dec_get(int code, vpiHandle ref)
{
switch (code) {
case vpiConstType:
return vpiDecConst;
case vpiSigned:
return 1;
case vpiSize:
return 32;
default:
fprintf(stderr, "vvp error: get %d not supported "
"by vpiDecConst\n", code);
assert(0);
return 0;
}
}
static void dec_value(vpiHandle ref, p_vpi_value vp)
{
struct __vpiDecConst*rfp = (struct __vpiDecConst*)ref;
char* cp;
assert(ref->vpi_type->type_code == vpiConstant);
switch (vp->format) {
case vpiObjTypeVal:
case vpiIntVal: {
vp->value.integer = rfp->value;
break;
}
case vpiDecStrVal:
sprintf(buf, "%d", rfp->value);
vp->format = vpiDecStrVal;
vp->value.str = buf;
break;
case vpiBinStrVal:
cp = buf;
for(int bit=31; bit<=0;bit--){
*cp++ = "01"[ (rfp->value>>bit)&1 ];
}
*cp = 0;
vp->format = vpiBinStrVal;
vp->value.str = buf;
break;
case vpiHexStrVal:
sprintf(buf, "%08x", rfp->value);
vp->format = vpiHexStrVal;
vp->value.str = buf;
break;
case vpiOctStrVal:
sprintf(buf, "%011x", rfp->value);
vp->format = vpiOctStrVal;
vp->value.str = buf;
break;
default:
fprintf(stderr, "vvp error (vpi_const.cc): format %d not supported "
"by vpiDecConst\n", vp->format);
vp->format = vpiSuppressVal;
break;
}
}
static const struct __vpirt vpip_dec_rt = {
vpiConstant,
dec_get,
0,
dec_value,
0,
0,
0
};
vpiHandle vpip_make_dec_const(int value)
{
struct __vpiDecConst*obj;
obj = (struct __vpiDecConst*)
malloc(sizeof (struct __vpiDecConst));
obj->base.vpi_type = &vpip_dec_rt;
obj->value = value;
return &(obj->base);
}
/*
* $Log: vpi_const.cc,v $
* Revision 1.11 2002/02/03 01:01:51 steve
* Use Larrys bits-to-decimal-string code.
*
* Revision 1.10 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.8 2002/01/15 03:21:18 steve
* Support DesSTrVal for binary constants.
*
* Revision 1.7 2001/09/15 18:27:05 steve
* Make configure detect malloc.h
*
+14 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vpi_mcd.cc,v 1.5 2001/07/16 18:40:19 steve Exp $"
#ident "$Id: vpi_mcd.cc,v 1.6 2002/01/04 02:26:36 steve Exp $"
#endif
# include "vpi_priv.h"
@@ -107,6 +107,10 @@ extern "C" int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap)
int len;
int rc;
// don't print to stderr twice
if (mcd_table[1].fp == mcd_table[2].fp && (mcd&6) == 6)
mcd &= ~2;
rc = len = 0;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1) {
@@ -123,6 +127,15 @@ extern "C" int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap)
return len;
}
extern "C" int vpi_mcd_printf(unsigned int mcd, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int r = vpi_mcd_vprintf(mcd,fmt,ap);
va_end(ap);
return r;
}
int vpi_mcd_fputc(unsigned int mcd, unsigned char x)
{
int i;
+53 -4
View File
@@ -27,7 +27,7 @@
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vpi_memory.cc,v 1.3 2001/12/07 23:23:05 steve Exp $"
#ident "$Id: vpi_memory.cc,v 1.4 2002/01/31 04:28:17 steve Exp $"
#endif
# include "vpi_priv.h"
@@ -40,6 +40,8 @@ struct __vpiMemoryWord {
struct __vpiHandle base;
struct __vpiMemory*mem;
int index;
struct __vpiDecConst*left_range;
struct __vpiDecConst*right_range;
};
struct __vpiMemory {
@@ -47,8 +49,28 @@ struct __vpiMemory {
/* The signal has a name (this points to static memory.) */
struct __vpiMemoryWord word;
vvp_memory_t mem;
struct __vpiDecConst*left_range;
struct __vpiDecConst*right_range;
};
static vpiHandle memory_get_handle(int code, vpiHandle obj)
{
struct __vpiMemory*rfp = (struct __vpiMemory*)obj;
assert(obj->vpi_type->type_code==vpiMemory);
switch(code){
case vpiLeftRange:
return &(rfp->left_range->base);
case vpiRightRange:
return &(rfp->right_range->base);
}
return 0;
}
static int vpi_memory_get(int code, vpiHandle ref)
{
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
@@ -139,6 +161,25 @@ static vpiHandle memory_index(vpiHandle ref, int index)
return &rfp->word.base;
}
//==============================
static vpiHandle memory_word_get_handle(int code, vpiHandle obj)
{
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)obj;
assert(obj->vpi_type->type_code==vpiMemoryWord);
switch(code){
case vpiLeftRange:
return &(rfp->left_range->base);
case vpiRightRange:
return &(rfp->right_range->base);
}
return 0;
}
static int memory_word_get(int code, vpiHandle ref)
{
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
@@ -234,7 +275,7 @@ static const struct __vpirt vpip_memory_rt = {
memory_get_str,
0,
0,
0,
memory_get_handle,
memory_iterate,
memory_index,
};
@@ -245,7 +286,7 @@ static const struct __vpirt vpip_memory_word_rt = {
0,
memory_word_get_value,
memory_word_put,
0,
memory_word_get_handle,
0,
0,
};
@@ -256,15 +297,23 @@ vpiHandle vpip_make_memory(vvp_memory_t mem)
malloc(sizeof(struct __vpiMemory));
obj->base.vpi_type = &vpip_memory_rt;
obj->word.base.vpi_type = &vpip_memory_word_rt;
obj->mem = mem;
obj->left_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_left_range(mem));
obj->right_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_right_range(mem));
obj->word.base.vpi_type = &vpip_memory_word_rt;
obj->word.mem = obj;
obj->word.left_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_word_left_range(mem));
obj->word.right_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_word_right_range(mem));
return &(obj->base);
}
/*
* $Log: vpi_memory.cc,v $
* Revision 1.4 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.3 2001/12/07 23:23:05 steve
* vpi_put_value of vpiIntVal for memory words.
*
+44 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_priv.cc,v 1.10 2001/10/31 04:27:47 steve Exp $"
#ident "$Id: vpi_priv.cc,v 1.12 2002/01/09 03:15:23 steve Exp $"
#endif
# include "vpi_priv.h"
@@ -87,6 +87,27 @@ void vpi_get_time(vpiHandle obj, s_vpi_time*vp)
vp->low = schedule_simtime();
}
static s_vpi_vlog_info vpi_vlog_info;
int vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p)
{
if (vlog_info_p != 0)
{
*vlog_info_p = vpi_vlog_info;
return 1;
}
else
return 0;
}
void vpi_set_vlog_info(int argc, char** argv)
{
vpi_vlog_info.product = "Icarus Verilog";
vpi_vlog_info.version = "$Name: $";
vpi_vlog_info.argc = argc;
vpi_vlog_info.argv = argv;
}
void vpi_get_value(vpiHandle expr, s_vpi_value*vp)
{
if (expr->vpi_type->vpi_get_value_) {
@@ -122,8 +143,24 @@ vpiHandle vpi_handle(int type, vpiHandle ref)
* the specified reference. It is up to the iterate_ method to
* allocate a properly formed iterator.
*/
static vpiHandle vpi_iterate_global(int type)
{
switch (type) {
case vpiModule:
return vpip_make_root_iterator();
default:
assert(0);
}
return 0;
}
vpiHandle vpi_iterate(int type, vpiHandle ref)
{
if (ref == 0)
return vpi_iterate_global(type);
assert(ref->vpi_type->iterate_);
return (ref->vpi_type->iterate_)(type, ref);
}
@@ -154,6 +191,12 @@ extern "C" void vpi_sim_vcontrol(int operation, va_list ap)
/*
* $Log: vpi_priv.cc,v $
* Revision 1.12 2002/01/09 03:15:23 steve
* Add vpi_get_vlog_info support.
*
* Revision 1.11 2002/01/06 00:48:39 steve
* VPI access to root module scopes.
*
* Revision 1.10 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+40 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_priv.h,v 1.24 2001/10/31 04:27:47 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.28 2002/02/03 01:01:51 steve Exp $"
#endif
# include "vpi_user.h"
@@ -93,6 +93,7 @@ struct __vpiScope {
extern struct __vpiScope* vpip_peek_current_scope(void);
extern void vpip_attach_to_current_scope(vpiHandle obj);
extern vpiHandle vpip_make_root_iterator(void);
/*
* Signals include the variable types (reg, integer, time) and are
@@ -182,6 +183,13 @@ struct __vpiBinaryConst {
vpiHandle vpip_make_binary_const(unsigned wid, char*bits);
struct __vpiDecConst {
struct __vpiHandle base;
int value;
};
vpiHandle vpip_make_dec_const(int value);
/*
* This one looks like a constant, but really is a vector in the current
* thread.
@@ -239,8 +247,39 @@ vpiHandle vpip_sim_time(void);
extern int vpip_get_time_precision(void);
extern void vpip_set_time_precision(int pres);
/*
** Functions defined in vpi_scope.cc, to keep track of functor scope.
*/
extern vpiHandle ipoint_get_scope(vvp_ipoint_t ipt);
extern void functor_set_scope(vpiHandle scope);
/*
* This function is used to make decimal string versions of various
* vectors. The input format is an array of bit values (0, 1, 2, 3)
* lsb first, and the result is written into buf, without overflowing
* nbuf.
*/
extern unsigned vpip_bits_to_dec_str(const unsigned char *bits,
unsigned int nbits,
char *buf, unsigned int nbuf,
int signed_flag);
/*
* $Log: vpi_priv.h,v $
* Revision 1.28 2002/02/03 01:01:51 steve
* Use Larrys bits-to-decimal-string code.
*
* Revision 1.27 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.26 2002/01/06 17:50:50 steve
* Support scope for functors. (Stephan Boettcher)
*
* Revision 1.25 2002/01/06 00:48:39 steve
* VPI access to root module scopes.
*
* Revision 1.24 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
+117 -23
View File
@@ -17,18 +17,27 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_scope.cc,v 1.10 2001/11/02 05:43:11 steve Exp $"
#ident "$Id: vpi_scope.cc,v 1.12 2002/01/06 17:50:50 steve Exp $"
#endif
# include "compile.h"
# include "vpi_priv.h"
# include "symbols.h"
# include "functor.h"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <assert.h>
static vpiHandle *vpip_root_table_ptr = 0;
static unsigned vpip_root_table_cnt = 0;
vpiHandle vpip_make_root_iterator(void)
{
return vpip_make_iterator(vpip_root_table_cnt, vpip_root_table_ptr);
}
static char* scope_get_str(int code, vpiHandle obj)
{
struct __vpiScope*ref = (struct __vpiScope*)obj;
@@ -97,6 +106,93 @@ static vpiHandle module_iter(int code, vpiHandle obj)
return 0;
}
/*
** Keeping track of functor scope. When the scope changes during
** compilation, we record the current number of functors in a list.
**
** Why are we doing this? The SDF annotator needs this for
** INTERCONNECT delays. The INTERCONNECT delay is specified between
** a source modules output port and a target module input port, which
** are connected with a wire. The vpiSignal for both ports point to
** the same functor output, together with all other ports that may be
** connected to the same wire. The SDF annotator need to find those
** functors which are inside the scope of the target module, which
** are driven by the source functor. And even this is only an
** aproximation, in case the wire is connected to multiple inputs of
** the same module. But those should have the same delays anyway.
**
*/
struct functor_scope_s {
vpiHandle scope;
unsigned start;
};
static struct functor_scope_s * functor_scopes = 0;
static unsigned n_functor_scopes = 0;
static unsigned a_functor_scopes = 0;
void functor_set_scope(vpiHandle scope)
{
unsigned nfun = functor_limit();
if (n_functor_scopes) {
functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
if (last->scope == scope) {
return;
}
if (last->start == nfun) {
last->scope = scope;
return;
}
}
n_functor_scopes += 1;
if (n_functor_scopes >= a_functor_scopes) {
a_functor_scopes += 512;
functor_scopes = (struct functor_scope_s *)
realloc(functor_scopes,
a_functor_scopes*sizeof(struct functor_scope_s));
assert(functor_scopes);
}
functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
last->start = nfun;
last->scope = scope;
}
/*
** Lockup the scope of a functor.
**
** Cannot use bserach, since we are not looking for an exact match
*/
vpiHandle ipoint_get_scope(vvp_ipoint_t ipt)
{
if (n_functor_scopes == 0)
return NULL;
unsigned fidx = ipt/4;
unsigned first = 0;
unsigned last = n_functor_scopes;
while (first < last) {
unsigned next = (first+last)/2;
functor_scope_s *cur = &functor_scopes[next];
if (cur->start > fidx)
last = next;
else if (next == first)
break;
else
first = next;
}
functor_scope_s *cur = &functor_scopes[first];
return cur->scope;
}
static const struct __vpirt vpip_scope_module_rt = {
vpiModule,
0,
@@ -175,19 +271,19 @@ void compile_scope_decl(char*label, char*type, char*name, char*parent)
struct __vpiScope*scope = new struct __vpiScope;
switch(type[2]) {
case 'd': /* type == module */
case 'd': /* type == moDule */
scope->base.vpi_type = &vpip_scope_module_rt;
break;
case 'n': /* type == function */
case 'n': /* type == fuNction */
scope->base.vpi_type = &vpip_scope_function_rt;
break;
case 's': /* type == task */
case 's': /* type == taSk */
scope->base.vpi_type = &vpip_scope_task_rt;
break;
case 'r': /* type == fork */
case 'r': /* type == foRk */
scope->base.vpi_type = &vpip_scope_fork_rt;
break;
case 'g': /* type == begin */
case 'g': /* type == beGin */
scope->base.vpi_type = &vpip_scope_begin_rt;
break;
default:
@@ -216,13 +312,22 @@ void compile_scope_decl(char*label, char*type, char*name, char*parent)
scope->scope = (struct __vpiScope*)obj;
} else {
scope->scope = 0x0;
unsigned cnt = vpip_root_table_cnt + 1;
vpip_root_table_ptr = (vpiHandle*)
realloc(vpip_root_table_ptr, cnt * sizeof(vpiHandle));
vpip_root_table_ptr[vpip_root_table_cnt] = &scope->base;
vpip_root_table_cnt = cnt;
}
functor_set_scope(&current_scope->base);
}
void compile_scope_recall(char*symbol)
{
compile_vpi_lookup((vpiHandle*)&current_scope, symbol);
assert(current_scope);
functor_set_scope(&current_scope->base);
}
struct __vpiScope* vpip_peek_current_scope(void)
@@ -238,6 +343,12 @@ void vpip_attach_to_current_scope(vpiHandle obj)
/*
* $Log: vpi_scope.cc,v $
* Revision 1.12 2002/01/06 17:50:50 steve
* Support scope for functors. (Stephan Boettcher)
*
* Revision 1.11 2002/01/06 00:48:39 steve
* VPI access to root module scopes.
*
* Revision 1.10 2001/11/02 05:43:11 steve
* Comment the scope type parser.
*
@@ -252,22 +363,5 @@ void vpip_attach_to_current_scope(vpiHandle obj)
*
* Revision 1.6 2001/07/11 04:43:57 steve
* support postpone of $systask parameters. (Stephan Boettcher)
*
* Revision 1.5 2001/06/10 16:47:49 steve
* support scan of scope from VPI.
*
* Revision 1.4 2001/04/18 04:21:23 steve
* Put threads into scopes.
*
* Revision 1.3 2001/04/03 03:46:14 steve
* VPI access time as a decimal string, and
* stub vpi access to the scopes.
*
* Revision 1.2 2001/03/21 05:13:03 steve
* Allow var objects as vpiHandle arguments to %vpi_call.
*
* Revision 1.1 2001/03/18 00:37:55 steve
* Add support for vpi scopes.
*
*/
+83 -140
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_signal.cc,v 1.30 2001/12/06 03:31:25 steve Exp $"
#ident "$Id: vpi_signal.cc,v 1.33 2002/02/03 01:01:51 steve Exp $"
#endif
/*
@@ -50,6 +50,23 @@ extern const char hex_digits[256];
extern const char oct_digits[256];
/*
* The string values need a result buf to hold the results. This
* buffer can be reused for that purpose. Whenever I have a need, the
* need_result_buf function makes sure that need can be met.
*/
static char*result_buf = 0;
static size_t result_buf_size = 0;
static void need_result_buf(size_t cnt)
{
if (result_buf_size == 0) {
result_buf = (char*)malloc(cnt);
} else if (result_buf_size < cnt) {
result_buf = (char*)realloc(result_buf, cnt);
}
result_buf_size = cnt;
}
/*
* implement vpi_get for vpiReg objects.
*/
@@ -122,7 +139,6 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
return 0;
}
static char buf[4096];
static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
{
@@ -130,97 +146,55 @@ static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
? (rfp->msb - rfp->lsb + 1)
: (rfp->lsb - rfp->msb + 1);
unsigned long val = 0;
unsigned count_x = 0, count_z = 0;
unsigned char*bits = new unsigned char[wid];
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, wid-idx-1);
val *= 2;
switch (functor_get(fptr)) {
case 0:
break;
case 1:
val += 1;
break;
case 2:
count_x += 1;
break;
case 3:
count_z += 1;
break;
}
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
bits[idx] = functor_get(fptr);
}
if (count_x == wid) {
buf[0] = 'x';
buf[1] = 0;
return;
}
need_result_buf((wid+2) / 3 + 1);
if (count_x > 0) {
buf[0] = 'X';
buf[1] = 0;
return;
}
vpip_bits_to_dec_str(bits, wid, result_buf, result_buf_size,
rfp->signed_flag);
if (count_z == wid) {
buf[0] = 'z';
buf[1] = 0;
return;
}
if (count_z > 0) {
buf[0] = 'Z';
buf[1] = 0;
return;
}
if (rfp->signed_flag) {
long tmp;
assert(sizeof(tmp) == sizeof(val));
if (val & (1<<(wid-1)) && wid < 8*sizeof(tmp)) {
tmp = -1;
tmp <<= wid;
tmp |= val;
} else {
tmp = val;
}
sprintf(buf, "%ld", tmp);
} else {
sprintf(buf, "%lu", val);
}
delete[]bits;
}
static void signal_vpiStringVal(struct __vpiSignal*rfp, s_vpi_value*vp)
{
char*cp;
unsigned idx;
unsigned wid = (rfp->msb >= rfp->lsb)
? (rfp->msb - rfp->lsb + 1)
: (rfp->lsb - rfp->msb + 1);
assert(wid % 8 == 0);
cp = buf;
for (idx = wid ; idx >= 8 ; idx -= 8) {
char tmp = 0;
unsigned bdx;
/* The result will use a character for each 8 bits of the
vector. Add one extra character for the highest bits that
don't form an 8 bit group. */
need_result_buf(wid/8 + ((wid&7)!=0) + 1);
for (bdx = 8 ; bdx > 0 ; bdx -= 1) {
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx-8+bdx-1);
tmp <<= 1;
switch (functor_get(fptr)) {
case 0:
break;
case 1:
tmp |= 1;
break;
default:
break;
}
}
*cp++ = tmp? tmp : ' ';
cp = result_buf;
char tmp = 0;
int bitnr;
for(bitnr=wid-1; bitnr>=0; bitnr--){
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, bitnr);
tmp <<= 1;
switch (functor_get(fptr)) {
case 0:
break;
case 1:
tmp |= 1;
break;
default:
break;
}
if ((bitnr&7)==0){
*cp++ = tmp? tmp : ' ';
tmp = 0;
}
}
*cp++ = 0;
}
@@ -263,18 +237,22 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
break;
case vpiBinStrVal:
need_result_buf(wid+1);
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
buf[wid-idx-1] = "01xz"[functor_get(fptr)];
result_buf[wid-idx-1] = "01xz"[functor_get(fptr)];
}
buf[wid] = 0;
vp->value.str = buf;
result_buf[wid] = 0;
vp->value.str = result_buf;
break;
case vpiHexStrVal: {
unsigned hval, hwid;
hwid = (wid + 3) / 4;
buf[hwid] = 0;
need_result_buf(hwid+1);
result_buf[hwid] = 0;
hval = 0;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
@@ -282,16 +260,16 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
if (idx%4 == 3) {
hwid -= 1;
buf[hwid] = hex_digits[hval];
result_buf[hwid] = hex_digits[hval];
hval = 0;
}
}
if (hwid > 0) {
hwid -= 1;
buf[hwid] = hex_digits[hval];
result_buf[hwid] = hex_digits[hval];
unsigned padd = 0;
switch(buf[hwid]) {
switch(result_buf[hwid]) {
case 'X': padd = 2; break;
case 'Z': padd = 3; break;
}
@@ -299,17 +277,19 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
for (unsigned idx = wid % 4; idx < 4; idx += 1) {
hval = hval | padd << 2*idx;
}
buf[hwid] = hex_digits[hval];
result_buf[hwid] = hex_digits[hval];
}
}
vp->value.str = buf;
vp->value.str = result_buf;
break;
}
case vpiOctStrVal: {
unsigned hval, hwid;
hwid = (wid + 2) / 3;
buf[hwid] = 0;
need_result_buf(hwid+1);
result_buf[hwid] = 0;
hval = 0;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
@@ -317,16 +297,16 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
if (idx%3 == 2) {
hwid -= 1;
buf[hwid] = oct_digits[hval];
result_buf[hwid] = oct_digits[hval];
hval = 0;
}
}
if (hwid > 0) {
hwid -= 1;
buf[hwid] = oct_digits[hval];
result_buf[hwid] = oct_digits[hval];
unsigned padd = 0;
switch(buf[hwid]) {
switch(result_buf[hwid]) {
case 'X': padd = 2; break;
case 'Z': padd = 3; break;
}
@@ -334,21 +314,21 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
for (unsigned idx = wid % 3; idx < 3; idx += 1) {
hval = hval | padd << 2*idx;
}
buf[hwid] = oct_digits[hval];
result_buf[hwid] = oct_digits[hval];
}
}
vp->value.str = buf;
vp->value.str = result_buf;
break;
}
case vpiDecStrVal:
signal_vpiDecStrVal(rfp, vp);
vp->value.str = buf;
vp->value.str = result_buf;
break;
case vpiStringVal:
signal_vpiStringVal(rfp, vp);
vp->value.str = buf;
vp->value.str = result_buf;
break;
case vpiVectorVal:
@@ -552,6 +532,15 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
/*
* $Log: vpi_signal.cc,v $
* Revision 1.33 2002/02/03 01:01:51 steve
* Use Larrys bits-to-decimal-string code.
*
* Revision 1.32 2002/01/09 03:29:12 steve
* String prints of non-round vectors (PR378)
*
* Revision 1.31 2001/12/18 05:31:54 steve
* Remove result length restrictions for vpi_get_value.
*
* Revision 1.30 2001/12/06 03:31:25 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
@@ -580,51 +569,5 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
* Nets (wires) do not use their own functors.
* Modifications to propagation of values.
* (Stephan Boettcher)
*
* Revision 1.22 2001/08/08 01:05:06 steve
* Initial implementation of vvp_fvectors.
* (Stephan Boettcher)
*
* Revision 1.21 2001/07/24 01:34:56 steve
* Implement string value for signals.
*
* Revision 1.20 2001/07/16 18:48:07 steve
* Properly pad unknow values. (Stephan Boettcher)
*
* Revision 1.19 2001/07/13 03:02:34 steve
* Rewire signal callback support for fast lookup. (Stephan Boettcher)
*
* Revision 1.18 2001/06/29 00:44:56 steve
* Properly support signal full names.
*
* Revision 1.17 2001/06/21 23:05:08 steve
* Some documentation of callback behavior.
*
* Revision 1.16 2001/06/21 22:54:12 steve
* Support cbValueChange callbacks.
*
* Revision 1.15 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.14 2001/05/22 04:08:49 steve
* correctly interpret signed decimal values.
*
* Revision 1.13 2001/05/15 15:09:08 steve
* Add the glossary file.
*
* Revision 1.12 2001/05/14 00:42:32 steve
* test width of target with bit size of long.
*
* Revision 1.11 2001/05/09 04:23:19 steve
* Now that the interactive debugger exists,
* there is no use for the output dump.
*
* Revision 1.10 2001/05/08 23:32:26 steve
* Add to the debugger the ability to view and
* break on functors.
*
* Add strengths to functors at compile time,
* and Make functors pass their strengths as they
* propagate their output.
*/

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