Compare commits

...
30 Commits
Author SHA1 Message Date
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
44 changed files with 981 additions and 376 deletions
+5 -1
View File
@@ -17,9 +17,10 @@
* 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.2 2001/12/18 04:52:45 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
# include <iostream>
# include <string.h>
@@ -249,6 +250,9 @@ ostream& operator<< (ostream&out, const hname_t&that)
/*
* $Log: HName.cc,v $
* 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.
+6 -4
View File
@@ -16,7 +16,7 @@
# 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.110 2001/12/30 17:20:33 steve Exp $"
#
#
SHELL = /bin/sh
@@ -46,6 +46,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)
@@ -170,14 +172,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.
+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)
+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.
+38 -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.48 2001/12/31 00:08:14 steve Exp $"
#endif
# include "config.h"
@@ -162,6 +162,26 @@ 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)
@@ -369,10 +389,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
@@ -642,6 +671,12 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/*
* $Log: elab_expr.cc,v $
* 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.
+65 -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_net.cc,v 1.82 2001/12/03 04:47:14 steve Exp $"
#ident "$Id: elab_net.cc,v 1.83 2001/12/30 21:32:03 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
@@ -1539,6 +1551,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 +1941,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* 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.
+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.
+9 -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: elaborate.cc,v 1.236 2001/12/06 05:04:49 steve Exp $"
#ident "$Id: elaborate.cc,v 1.238 2001/12/31 00:39:20 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);
@@ -2394,6 +2394,12 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
* 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.
*
+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.
+21 -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.31 2001/12/30 00:39:25 steve Exp $"
#endif
# include "config.h"
@@ -911,6 +911,23 @@ 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());
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 +1019,9 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* 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.
*
+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_target.h,v 1.89 2001/12/06 03:11:00 steve Exp $"
#ident "$Id: ivl_target.h,v 1.90 2001/12/15 02:13:17 steve Exp $"
#endif
#ifdef __cplusplus
@@ -258,7 +258,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 +976,10 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* 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.
*
+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; }
+14 -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.179 2001/12/31 00:08: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();
@@ -2214,6 +2215,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 +2226,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 +2239,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;
@@ -2407,6 +2405,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* 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.
+7 -7
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: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $"
#ident "$Id: netlist.h,v 1.228 2001/12/31 00:08:14 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;
@@ -2501,10 +2502,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 +2864,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* 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.
+4 -4
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.142 2001/12/30 21:32:03 steve Exp $"
#endif
# include "config.h"
@@ -36,6 +36,7 @@ extern void lex_end_table();
* net_decl_assigns can change them during specific statements.
*/
static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
%}
%union {
@@ -818,7 +819,6 @@ expr_primary
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
| identifier
{ PEIdent*tmp = new PEIdent(*$1);
@@ -1260,10 +1260,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 ';'
+5 -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.21 2001/12/31 00:08:14 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)) {
@@ -347,6 +347,9 @@ void dll_target::expr_unary(const NetEUnary*net)
/*
* $Log: t-dll-expr.cc,v $
* 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.
*
+63 -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-dll.cc,v 1.71 2001/12/06 03:11:00 steve Exp $"
#ident "$Id: t-dll.cc,v 1.74 2001/12/18 05:34:02 steve Exp $"
#endif
# include "config.h"
@@ -247,7 +247,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,6 +261,8 @@ 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)
@@ -602,11 +606,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());
@@ -1302,6 +1347,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;
@@ -1605,7 +1654,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 +1723,16 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* 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.
*
+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)
*
+113 -18
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.60 2001/12/15 02:13:33 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -126,6 +126,31 @@ 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;
}
/*
* The draw_scope function draws the major functional items within a
* scope. This includes the scopes themselves, of course. All the
@@ -196,14 +221,6 @@ 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);
@@ -270,6 +287,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 +295,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 +356,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 +392,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 +589,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;
@@ -616,13 +684,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 +698,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 +737,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) {
@@ -1235,6 +1321,15 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* 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)
+18 -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: verinum.cc,v 1.29 2001/11/19 02:54:12 steve Exp $"
#ident "$Id: verinum.cc,v 1.30 2001/12/31 00:02:33 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 << "'sb";
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";
@@ -786,6 +793,9 @@ verinum::V operator & (verinum::V l, verinum::V r)
/*
* $Log: verinum.cc,v $
* 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.
+5 -3
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.33 2001/12/30 17:20:33 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@
@@ -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
$(YACC) --verbose -t -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h 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
+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.
+14 -2
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.117 2001/12/15 02:11:51 steve Exp $"
#endif
# include "arith.h"
@@ -858,7 +858,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 +1350,12 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
/*
* $Log: compile.cc,v $
* 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)
+6 -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.39 2001/12/14 02:04:49 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);
@@ -222,6 +223,9 @@ extern void compile_net(char*label, char*name,
/*
* $Log: compile.h,v $
* 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
*
+24 -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.3 2001/12/29 23:59:06 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
out 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,9 @@ void compile_event(char*label, char*type,
/*
* $Log: event.cc,v $
* 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.
*
+46 -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.37 2001/12/18 05:32:11 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
@@ -71,26 +71,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 +100,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 +123,7 @@ functor_s::functor_s()
cstr = StX;
inhibit = 0;
#if defined(WITH_DEBUG)
breakpoint = 0;
break_flag = 0;
#endif
}
@@ -169,8 +170,38 @@ 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.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 +228,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.
*/
+17 -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.42 2001/12/18 05:32:11 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
@@ -119,12 +122,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 +177,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 +224,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 +303,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 +379,12 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
/*
* $Log: functor.h,v $
* 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)
+32 -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.6 2001/12/14 06:03:17 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,25 @@ 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, "PMOS") == 0) {
obj = new vvp_pmos_s;
@@ -102,19 +107,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 +152,12 @@ void compile_functor(char*label, char*type,
/*
* $Log: logic.cc,v $
* 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)
+11 -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.2 2001/12/14 02:04:49 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;
};
@@ -56,6 +61,9 @@ extern const unsigned char ft_var[];
/*
* $Log: logic.h,v $
* 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)
*
+13 -5
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.42 2001/12/14 02:04:49 steve Exp $"
#endif
# include "parse_misc.h"
@@ -119,13 +119,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
@@ -527,6 +532,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* 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.
+67 -76
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.31 2001/12/18 05:31:54 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)
{
@@ -152,29 +168,35 @@ static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
}
if (count_x == wid) {
buf[0] = 'x';
buf[1] = 0;
need_result_buf(2);
result_buf[0] = 'x';
result_buf[1] = 0;
return;
}
if (count_x > 0) {
buf[0] = 'X';
buf[1] = 0;
need_result_buf(2);
result_buf[0] = 'X';
result_buf[1] = 0;
return;
}
if (count_z == wid) {
buf[0] = 'z';
buf[1] = 0;
need_result_buf(2);
result_buf[0] = 'z';
result_buf[1] = 0;
return;
}
if (count_z > 0) {
buf[0] = 'Z';
buf[1] = 0;
need_result_buf(2);
result_buf[0] = 'Z';
result_buf[1] = 0;
return;
}
need_result_buf((wid+2) / 3 + 1);
if (rfp->signed_flag) {
long tmp;
assert(sizeof(tmp) == sizeof(val));
@@ -185,10 +207,12 @@ static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
} else {
tmp = val;
}
sprintf(buf, "%ld", tmp);
sprintf(result_buf, "%ld", tmp);
assert(strlen(result_buf) < result_buf_size);
} else {
sprintf(buf, "%lu", val);
sprintf(result_buf, "%lu", val);
assert(strlen(result_buf) < result_buf_size);
}
}
@@ -202,7 +226,11 @@ static void signal_vpiStringVal(struct __vpiSignal*rfp, s_vpi_value*vp)
assert(wid % 8 == 0);
cp = buf;
/* The result will use a character for each 8 bits of the
vector. */
need_result_buf(wid/8 + 1);
cp = result_buf;
for (idx = wid ; idx >= 8 ; idx -= 8) {
char tmp = 0;
unsigned bdx;
@@ -263,18 +291,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 +314,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 +331,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 +351,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 +368,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 +586,9 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
/*
* $Log: vpi_signal.cc,v $
* 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 +617,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.
*/
+35 -1
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_vthr_vector.cc,v 1.3 2001/09/15 18:27:05 steve Exp $"
#ident "$Id: vpi_vthr_vector.cc,v 1.4 2001/12/30 21:31:38 steve Exp $"
#endif
/*
@@ -162,6 +162,29 @@ static void vthr_vec_DecStrVal(struct __vpiVThrVec*rfp, s_vpi_value*vp)
sprintf(buf, "%lu", val);
}
static void vthr_vec_StringVal(struct __vpiVThrVec*rfp, s_vpi_value*vp)
{
assert(rfp->wid % 8 == 0);
assert(rfp->wid/8 < sizeof buf);
unsigned bytes = rfp->wid/8;
for (unsigned idx = 0 ; idx < bytes ; idx += 1) {
unsigned base = rfp->wid - 8 - idx * 8;
int val = 0;
for (unsigned bit = 0 ; bit < 8 ; bit += 1) {
unsigned tmp = get_bit(rfp, base+bit);
if (tmp == 1)
val |= 1 << bit;
}
buf[idx] = val? val : ' ';
}
buf[bytes] = 0;
}
/*
* The get_value method reads the values of the functors and returns
* the vector to the caller. This causes no side-effect, and reads the
@@ -180,6 +203,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
switch (vp->format) {
case vpiBinStrVal:
assert(wid < sizeof buf);
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
buf[wid-idx-1] = "01xz"[get_bit(rfp, idx)];
}
@@ -190,6 +214,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
case vpiHexStrVal: {
unsigned hval, hwid;
hwid = (wid + 3) / 4;
assert(hwid < sizeof buf);
buf[hwid] = 0;
hval = 0;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
@@ -214,6 +239,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
case vpiOctStrVal: {
unsigned hval, hwid;
hwid = (wid + 2) / 3;
assert(hwid < sizeof buf);
buf[hwid] = 0;
hval = 0;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
@@ -240,6 +266,11 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
vp->value.str = buf;
break;
case vpiStringVal:
vthr_vec_StringVal(rfp, vp);
vp->value.str = buf;
break;
default:
/* XXXX Not implemented yet. */
assert(0);
@@ -348,6 +379,9 @@ vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid)
/*
* $Log: vpi_vthr_vector.cc,v $
* Revision 1.4 2001/12/30 21:31:38 steve
* Support vpiStringVal in vhtread vectors.
*
* Revision 1.3 2001/09/15 18:27:05 steve
* Make configure detect malloc.h
*
+30 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vthread.cc,v 1.64 2001/11/06 03:07:22 steve Exp $"
#ident "$Id: vthread.cc,v 1.65 2001/12/31 00:01:16 steve Exp $"
#endif
# include "vthread.h"
@@ -420,8 +420,11 @@ bool of_CMPS(vthread_t thr, vvp_code_t cp)
unsigned idx1 = cp->bit_idx[0];
unsigned idx2 = cp->bit_idx[1];
unsigned sig1 = thr_get_bit(thr, idx1 + cp->number - 1);
unsigned sig2 = thr_get_bit(thr, idx2 + cp->number - 1);
unsigned end1 = (idx1 < 4)? idx1 : idx1 + cp->number - 1;
unsigned end2 = (idx2 < 4)? idx2 : idx2 + cp->number - 1;
unsigned sig1 = thr_get_bit(thr, end1);
unsigned sig2 = thr_get_bit(thr, end2);
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
unsigned lv = thr_get_bit(thr, idx1);
@@ -454,6 +457,27 @@ bool of_CMPS(vthread_t thr, vvp_code_t cp)
else if ((sig1 == 0) && (sig2 == 1))
lt = 0;
/* Correct the lt bit to account for the sign of the parameters. */
if (lt < 2) {
sig1 = thr_get_bit(thr, end1);
sig2 = thr_get_bit(thr, end2);
/* If both numbers are negative, then switch the
direction of the lt. */
if ((sig1 == 1) && (sig2 == 1) && (eq != 0))
lt ^= 1;
/* If the first is negative and the last positive, then
a < b for certain. */
if ((sig1 == 1) && (sig2 == 0))
lt = 1;
/* If the first is positive and the last negative, then
a > b for certain. */
if ((sig1 == 0) && (sig2 == 1))
lt = 0;
}
thr_put_bit(thr, 4, eq);
thr_put_bit(thr, 5, lt);
thr_put_bit(thr, 6, eeq);
@@ -1672,6 +1696,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
/*
* $Log: vthread.cc,v $
* Revision 1.65 2001/12/31 00:01:16 steve
* Account for negatives in cmp/s
*
* Revision 1.64 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*