Merge remote-tracking branch 'origin/master' into package-imports-rework

This commit is contained in:
Martin Whitaker 2019-10-01 09:06:15 +01:00
commit f69eccf903
39 changed files with 479 additions and 232 deletions

View File

@ -175,7 +175,8 @@ endif
rm -rf autom4te.cache
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^

View File

@ -299,20 +299,20 @@ PDoWhile::~PDoWhile()
}
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0), search_funcs_(false)
: expr_(ee), statement_(0), always_sens_(false)
{
assert(expr_.count() > 0);
}
PEventStatement::PEventStatement(PEEvent*ee)
: expr_(1), statement_(0), search_funcs_(false)
: expr_(1), statement_(0), always_sens_(false)
{
expr_[0] = ee;
}
PEventStatement::PEventStatement(bool search_funcs)
: statement_(0), search_funcs_(search_funcs)
PEventStatement::PEventStatement(bool always_sens)
: statement_(0), always_sens_(always_sens)
{
}

View File

@ -405,8 +405,8 @@ class PEventStatement : public Statement {
explicit PEventStatement(const svector<PEEvent*>&ee);
explicit PEventStatement(PEEvent*ee);
// Make an @* statement or make a special @* version with the items
// from functions added and ouputs removed for always_comb/latch.
explicit PEventStatement(bool search_funcs = false);
// from functions added and outputs removed for always_comb/latch.
explicit PEventStatement(bool always_sens = false);
~PEventStatement();
@ -432,7 +432,7 @@ class PEventStatement : public Statement {
private:
svector<PEEvent*>expr_;
Statement*statement_;
bool search_funcs_;
bool always_sens_;
};
ostream& operator << (ostream&o, const PEventStatement&obj);

View File

@ -59,7 +59,7 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f $(INCLUDE_PATH) $^
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=cadpli/$@

View File

@ -66,7 +66,7 @@ distclean: clean
rm -f Makefile config.log
cppcheck: main.c
cppcheck --enable=all -f $(INCLUDE_PATH) $^
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@

View File

@ -67,7 +67,7 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
-UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -2017,7 +2017,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
// If the member type is a netvector_t, then it is a
// vector of atom or scaler objects. For example, if the
// l-value expression is "foo.member[1][2]",
// l-value expression is "foo.member[1][2]",
// then the member should be something like:
// ... logic [h:l][m:n] member;
// There should be index expressions index the vector

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -1265,7 +1265,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type)) {
// If the member type is a netvector_t, then it is a
// vector of atom or scaler objects. For example, if the
// l-value expression is "foo.member[1][2]",
// l-value expression is "foo.member[1][2]",
// then the member should be something like:
// ... logic [h:l][m:n] member;
// There should be index expressions index the vector

View File

@ -453,7 +453,9 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
if (debug_scopes) {
cerr << pclass->get_fileline() <<": elaborate_scope_class: "
<< "Elaborate scope class " << pclass->pscope_name() << endl;
<< "Elaborate scope class " << pclass->pscope_name()
<< " within scope " << scope_path(scope)
<< endl;
}
class_type_t*base_class = dynamic_cast<class_type_t*> (use_type->base_type);
@ -491,12 +493,24 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
use_class->set_definition_scope(scope);
set_scope_timescale(des, class_scope, pclass);
// Elaborate enum types declared in the class. We need these
// now because enumeration constants can be used during scope
// elaboration.
if (debug_scopes) {
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
<< "Elaborate " << pclass->enum_sets.size() << " enumerations"
<< " in class " << scope_path(class_scope)
<< ", scope=" << scope_path(scope) << "."
<< endl;
}
elaborate_scope_enumerations(des, class_scope, pclass->enum_sets);
// Collect the properties, elaborate them, and add them to the
// elaborated class definition.
for (map<perm_string, class_type_t::prop_info_t>::iterator cur = use_type->properties.begin()
; cur != use_type->properties.end() ; ++ cur) {
ivl_type_s*tmp = cur->second.type->elaborate_type(des, scope);
ivl_type_s*tmp = cur->second.type->elaborate_type(des, class_scope);
ivl_assert(*pclass, tmp);
if (debug_scopes) {
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
@ -699,7 +713,15 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
collect_scope_parameters_(des, scope, parameters);
collect_scope_localparams_(des, scope, localparams);
if (debug_scopes) {
cerr << get_fileline() << ": PPackage::elaborate_scope: "
<< "Elaborate " << enum_sets.size() << " enumerations"
<< " in package scope " << scope_path(scope) << "."
<< endl;
}
elaborate_scope_enumerations(des, scope, enum_sets);
elaborate_scope_classes(des, scope, classes_lexical);
elaborate_scope_funcs(des, scope, funcs);
elaborate_scope_tasks(des, scope, tasks);
@ -736,6 +758,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
replace_scope_parameters_(scope, *this, replacements);
if (debug_scopes) {
cerr << get_fileline() << ": Module::elaborate_scope: "
<< "Elaborate " << enum_sets.size() << " enumerations"
<< " in scope " << scope_path(scope) << "."
<< endl;
}
elaborate_scope_enumerations(des, scope, enum_sets);
assert(classes.size() == classes_lexical.size());

View File

@ -29,6 +29,7 @@
# include <typeinfo>
# include <cstdlib>
# include <iostream>
# include <sstream>
# include <list>
# include "pform.h"
@ -4221,13 +4222,13 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
* a value to change. */
extern bool synthesis; /* Synthesis flag from main.cc */
bool rem_out = false;
if (synthesis || search_funcs_) {
if (synthesis || always_sens_) {
rem_out = true;
}
// If this is an always_comb/latch then we need an implicit T0
// trigger of the event expression.
if (search_funcs_) wa->set_t0_trigger();
NexusSet*nset = enet->nex_input(rem_out, search_funcs_);
if (always_sens_) wa->set_t0_trigger();
NexusSet*nset = enet->nex_input(rem_out, always_sens_);
if (nset == 0) {
cerr << get_fileline() << ": error: Unable to elaborate:"
<< endl;
@ -4237,6 +4238,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
}
if (nset->size() == 0) {
if (always_sens_) return wa;
cerr << get_fileline() << ": warning: @* found no "
"sensitivities so it will never trigger."
<< endl;
@ -4256,8 +4259,38 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
ev, NetEvProbe::ANYEDGE,
nset->size());
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1)
connect(nset->at(idx).lnk, pr->pin(idx));
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1) {
unsigned wid = nset->at(idx).wid;
unsigned vwid = nset->at(idx).lnk.nexus()->vector_width();
// Is this a part select?
if (always_sens_ && (wid != vwid)) {
cerr << get_fileline() << ": sorry: constant "
"selects in always_* processes are not "
"currently supported (all bits will be "
"included)." << endl;
# if 0
unsigned base = nset->at(idx).base;
// FIXME: Is this needed since you can select past the vector?
assert((base + wid) <= vwid);
cerr << get_fileline() << ": base = " << base << ", width = " << wid
<< ", expr width = " << vwid << endl;
nset->at(idx).lnk.dump_link(cerr, 4);
cerr << endl;
// FIXME: Convert the link to the appropriate NetNet
netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, vwid, 0);
NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec);
NetPartSelect*tmp = new NetPartSelect(sig, base, wid, NetPartSelect::VP);
des->add_node(tmp);
tmp->set_line(*this);
// FIXME: create a part select to get the correct bits to connect.
connect(tmp->pin(1), nset->at(idx).lnk);
connect(tmp->pin(0), pr->pin(idx));
# endif
connect(nset->at(idx).lnk, pr->pin(idx));
} else {
connect(nset->at(idx).lnk, pr->pin(idx));
}
}
delete nset;
des->add_node(pr);
@ -6136,6 +6169,31 @@ class later_defparams : public elaborator_work_item_t {
}
};
static ostream& operator<< (ostream&o, ivl_process_type_t t)
{
switch (t) {
case IVL_PR_ALWAYS:
o << "always";
break;
case IVL_PR_ALWAYS_COMB:
o << "always_comb";
break;
case IVL_PR_ALWAYS_FF:
o << "always_ff";
break;
case IVL_PR_ALWAYS_LATCH:
o << "always_latch";
break;
case IVL_PR_INITIAL:
o << "initial";
break;
case IVL_PR_FINAL:
o << "final";
break;
}
return o;
}
bool Design::check_proc_delay() const
{
bool result = false;
@ -6145,55 +6203,66 @@ bool Design::check_proc_delay() const
* a runtime infinite loop will happen. If we possibly have some
* delay then print a warning that an infinite loop is possible.
*/
if ((pr->type() == IVL_PR_ALWAYS) ||
(pr->type() == IVL_PR_ALWAYS_COMB) ||
(pr->type() == IVL_PR_ALWAYS_FF) ||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
if (pr->type() == IVL_PR_ALWAYS) {
DelayType dly_type = pr->statement()->delay_type();
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
cerr << pr->get_fileline() << ": error: always"
<< " statement does not have any delay." << endl;
cerr << pr->get_fileline() << ": : A runtime"
<< " infinite loop will occur." << endl;
cerr << pr->get_fileline() << ": error: always "
"process does not have any delay." << endl;
cerr << pr->get_fileline() << ": : A runtime "
"infinite loop will occur." << endl;
result = true;
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
cerr << pr->get_fileline() << ": warning: always"
<< " statement may not have any delay." << endl;
cerr << pr->get_fileline() << ": : A runtime"
<< " infinite loop may be possible." << endl;
cerr << pr->get_fileline() << ": warning: always "
"process may not have any delay." << endl;
cerr << pr->get_fileline() << ": : A runtime "
<< "infinite loop may be possible." << endl;
}
}
// The always_comb/ff/latch processes have special delay rules
// that need to be checked.
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
(pr->type() == IVL_PR_ALWAYS_FF) ||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
const NetEvWait *wait = dynamic_cast<const NetEvWait*> (pr->statement());
if (! wait) {
// The always_comb/latch processes have an event
// control added automatically by the compiler.
assert(pr->type() == IVL_PR_ALWAYS_FF);
cerr << pr->get_fileline() << ": error: the first "
"statement of an always_ff process must be "
"an event control statement." << endl;
result = true;
} else if (wait->statement()->delay_type(true) != NO_DELAY) {
cerr << pr->get_fileline() << ": error: there must ";
if (pr->type() == IVL_PR_ALWAYS_FF) {
cerr << "only be a single event control and "
"no blocking delays in an always_ff "
"process.";
} else {
cerr << "be no event controls or blocking "
"delays in an " << pr->type()
<< " process.";
}
cerr << endl;
result = true;
}
// The always_comb/ff/latch processes also have special
// delay rules that need to be checked.
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
(pr->type() == IVL_PR_ALWAYS_FF) ||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
const NetEvWait *wait = dynamic_cast<const NetEvWait*> (pr->statement());
if (! wait) {
// The always_comb/latch processes have an event
// control added automatically by the compiler.
assert(pr->type() == IVL_PR_ALWAYS_FF);
cerr << pr->get_fileline() << ": error: the "
<< "first statement of an always_ff must "
<< "be an event control." << endl;
result = true;
} else if (wait->statement()->delay_type(true) != NO_DELAY) {
cerr << pr->get_fileline() << ": error: there "
<< "must ";
if (pr->type() == IVL_PR_ALWAYS_FF) {
cerr << "only be a single event control "
<< "and no blocking delays in an "
<< "always_ff process.";
} else {
cerr << "be no event controls or blocking "
<< "delays in an always_comb/latch "
<< "process.";
}
cerr << endl;
if ((pr->type() != IVL_PR_ALWAYS_FF) &&
(wait->nevents() == 0)) {
if (pr->type() == IVL_PR_ALWAYS_LATCH) {
cerr << pr->get_fileline() << ": error: "
"always_latch process has no event "
"control." << endl;
result = true;
} else {
assert(pr->type() == IVL_PR_ALWAYS_COMB);
cerr << pr->get_fileline() << ": warning: "
"always_comb process has no "
"sensitivities." << endl;
}
}
}

View File

@ -60,7 +60,7 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f $(INCLUDE_PATH) $^
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=ivlpp/$@

View File

@ -76,8 +76,9 @@ distclean: clean
rm -f config.h stamp-config-h
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in
cd ..; ./config.status --file=libveriuser/$@

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2017 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2019 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,8 +19,8 @@
# include "config.h"
# include <iostream>
# include <iostream>
# include <set>
# include <cassert>
# include <typeinfo>
# include "compiler.h"
@ -43,13 +43,13 @@ NexusSet* NetProc::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
if (items_[idx]==0) continue;
NexusSet*tmp = items_[idx]->nex_input(rem_out, search_funcs);
NexusSet*tmp = items_[idx]->nex_input(rem_out, always_sens);
if (tmp == 0) continue;
result->add(*tmp);
@ -58,25 +58,25 @@ NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetEBinary::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEBinary::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = left_->nex_input(rem_out, search_funcs);
NexusSet*tmp = right_->nex_input(rem_out, search_funcs);
NexusSet*result = left_->nex_input(rem_out, always_sens);
NexusSet*tmp = right_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
return result;
}
NexusSet* NetEConcat::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEConcat::nex_input(bool rem_out, bool always_sens) const
{
if (parms_[0] == NULL) return new NexusSet;
NexusSet*result = parms_[0]->nex_input(rem_out, search_funcs);
NexusSet*result = parms_[0]->nex_input(rem_out, always_sens);
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
if (parms_[idx] == NULL) {
delete result;
return new NexusSet;
}
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -136,14 +136,27 @@ NexusSet* NetEScope::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetESelect::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetESelect::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = base_? base_->nex_input(rem_out, search_funcs) : new NexusSet();
NexusSet*tmp = expr_->nex_input(rem_out, search_funcs);
NexusSet*result = base_? base_->nex_input(rem_out, always_sens) : new NexusSet();
NexusSet*tmp = expr_->nex_input(rem_out, always_sens);
bool const_select = result->size() == 0;
if (always_sens && const_select) {
if (NetEConst *val = dynamic_cast <NetEConst*> (base_)) {
assert(select_type() == IVL_SEL_OTHER);
if (NetESignal *sig = dynamic_cast<NetESignal*> (expr_)) {
delete tmp;
tmp = sig->nex_input_base(rem_out, always_sens, val->value().as_unsigned(), expr_width());
} else {
cerr << get_fileline() << ": Sorry, cannot determine the sensitivity "
<< "for the select of " << *expr_ << ", using all bits." << endl;
}
}
}
result->add(*tmp);
delete tmp;
/* See the comment for NetESignal below. */
if (base_ && warn_sens_entire_vec) {
if (base_ && ! always_sens && warn_sens_entire_vec) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
"bits in '" << *expr_ << "'." << endl;
}
@ -153,7 +166,7 @@ NexusSet* NetESelect::nex_input(bool rem_out, bool search_funcs) const
/*
* The $fread, etc. system functions can have NULL arguments.
*/
NexusSet* NetESFunc::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetESFunc::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
@ -161,7 +174,7 @@ NexusSet* NetESFunc::nex_input(bool rem_out, bool search_funcs) const
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
if (parms_[idx]) {
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -175,7 +188,12 @@ NexusSet* NetEShallowCopy::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetESignal::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetESignal::nex_input(bool rem_out, bool always_sens) const
{
return nex_input_base(rem_out, always_sens, 0, 0);
}
NexusSet* NetESignal::nex_input_base(bool rem_out, bool always_sens, unsigned base, unsigned width) const
{
/*
* This is not what I would expect for the various selects (bit,
@ -183,55 +201,76 @@ NexusSet* NetESignal::nex_input(bool rem_out, bool search_funcs) const
* instead of building the appropriate select and then using it
* as the trigger. Other simulators also add everything.
*/
bool const_select = false;
unsigned const_word = 0;
NexusSet*result = new NexusSet;
/* Local signals are not added to the sensitivity list. */
if (net_->local_flag()) return result;
/* If we have an array index add it to the sensitivity list. */
if (word_) {
NexusSet*tmp;
tmp = word_->nex_input(rem_out, search_funcs);
tmp = word_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
if (warn_sens_entire_arr) {
if (!always_sens && warn_sens_entire_arr) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
<< net_->unpacked_count() << " words in array '"
<< name() << "'." << endl;
}
if (always_sens) if (NetEConst *val = dynamic_cast <NetEConst*> (word_)) {
const_select = true;
const_word = val->value().as_unsigned();
}
}
if ((base == 0) && (width == 0)) width = net_->vector_width();
if (const_select) {
result->add(net_->pin(const_word).nexus(), base, width);
} else {
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
result->add(net_->pin(idx).nexus(), base, width);
}
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
result->add(net_->pin(idx).nexus(), 0, net_->vector_width());
return result;
}
NexusSet* NetETernary::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetETernary::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*tmp;
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
NexusSet*result = cond_->nex_input(rem_out, always_sens);
tmp = true_val_->nex_input(rem_out, search_funcs);
tmp = true_val_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
tmp = false_val_->nex_input(rem_out, search_funcs);
tmp = false_val_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
return result;
}
NexusSet* NetEUFunc::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens) const
{
static set<string> func_set;
NexusSet*result = new NexusSet;
string func_name;
// Avoid recursive function calls.
func_name = scope_->fullname().peek_name();
if (! scope_->parent()) func_set.clear();
if (! func_set.insert(func_name).second) return result;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (search_funcs) {
if (always_sens) {
NetFuncDef*func = func_->func_def();
NexusSet*tmp = func->proc()->nex_input(rem_out, search_funcs);
NexusSet*tmp = func->proc()->nex_input(rem_out, always_sens);
// Remove the function inputs
NexusSet*in = new NexusSet;
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
@ -249,9 +288,9 @@ NexusSet* NetEUFunc::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetEUnary::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEUnary::nex_input(bool rem_out, bool always_sens) const
{
return expr_->nex_input(rem_out, search_funcs);
return expr_->nex_input(rem_out, always_sens);
}
NexusSet* NetAlloc::nex_input(bool, bool) const
@ -259,18 +298,18 @@ NexusSet* NetAlloc::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetAssign_::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetAssign_::nex_input(bool rem_out, bool always_sens) const
{
assert(! nest_);
NexusSet*result = new NexusSet;
if (word_) {
NexusSet*tmp = word_->nex_input(rem_out, search_funcs);
NexusSet*tmp = word_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (base_) {
NexusSet*tmp = base_->nex_input(rem_out, search_funcs);
NexusSet*tmp = base_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -278,12 +317,12 @@ NexusSet* NetAssign_::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetAssignBase::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetAssignBase::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
// For the deassign and release statements there is no R-value.
if (rval_) {
NexusSet*tmp = rval_->nex_input(rem_out, search_funcs);
NexusSet*tmp = rval_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -292,7 +331,7 @@ NexusSet* NetAssignBase::nex_input(bool rem_out, bool search_funcs) const
particular, index expressions are statement inputs as well,
so should be addressed here. */
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
NexusSet*tmp = cur->nex_input(rem_out, search_funcs);
NexusSet*tmp = cur->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -317,11 +356,11 @@ NexusSet* NetAssignBase::nex_input(bool rem_out, bool search_funcs) const
* In this example, "t" should not be in the input set because it is
* used by the sequence as a temporary value.
*/
NexusSet* NetBlock::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetBlock::nex_input(bool rem_out, bool always_sens) const
{
if (last_ == 0) return new NexusSet;
if (! search_funcs && (type_ != SEQU)) {
if (! always_sens && (type_ != SEQU)) {
cerr << get_fileline() << ": internal error: Sorry, "
<< "I don't know how to synthesize fork/join blocks."
<< endl;
@ -336,7 +375,7 @@ NexusSet* NetBlock::nex_input(bool rem_out, bool search_funcs) const
do {
/* Get the inputs for the current statement. */
NexusSet*tmp = cur->nex_input(rem_out, search_funcs);
NexusSet*tmp = cur->nex_input(rem_out, always_sens);
/* Add the current input set to the accumulated input set. */
result->add(*tmp);
@ -363,9 +402,9 @@ NexusSet* NetBlock::nex_input(bool rem_out, bool search_funcs) const
* the inputs to all the guards, and the inputs to all the guarded
* statements.
*/
NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetCase::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
NexusSet*result = expr_->nex_input(rem_out, always_sens);
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
@ -373,7 +412,7 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
if (items_[idx].statement == 0)
continue;
NexusSet*tmp = items_[idx].statement->nex_input(rem_out, search_funcs);
NexusSet*tmp = items_[idx].statement->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
@ -381,7 +420,7 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
case is special and is identified by a null
guard. The default guard obviously has no input. */
if (items_[idx].guard) {
tmp = items_[idx].guard->nex_input(rem_out, search_funcs);
tmp = items_[idx].guard->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -390,18 +429,18 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetCondit::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetCondit::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
NexusSet*result = expr_->nex_input(rem_out, always_sens);
if (if_ != 0) {
NexusSet*tmp = if_->nex_input(rem_out, search_funcs);
NexusSet*tmp = if_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (else_ != 0) {
NexusSet*tmp = else_->nex_input(rem_out, search_funcs);
NexusSet*tmp = else_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -414,12 +453,12 @@ NexusSet* NetDisable::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetDoWhile::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetDoWhile::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
NexusSet*result = cond_->nex_input(rem_out, always_sens);
if (proc_) {
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
NexusSet*tmp = proc_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -432,12 +471,12 @@ NexusSet* NetEvTrig::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetEvWait::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetEvWait::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
if (statement_) {
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -445,12 +484,12 @@ NexusSet* NetEvWait::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetForever::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetForever::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
if (statement_) {
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -458,30 +497,30 @@ NexusSet* NetForever::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetForLoop::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetForLoop::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
if (init_expr_) {
NexusSet*tmp = init_expr_->nex_input(rem_out, search_funcs);
NexusSet*tmp = init_expr_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (condition_) {
NexusSet*tmp = condition_->nex_input(rem_out, search_funcs);
NexusSet*tmp = condition_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (step_statement_) {
NexusSet*tmp = step_statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = step_statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
if (statement_) {
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -512,12 +551,12 @@ NexusSet* NetFree::nex_input(bool, bool) const
* include the input set of the <expr> because it does not affect the
* result. The statement can be omitted.
*/
NexusSet* NetPDelay::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetPDelay::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
if (statement_) {
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -525,12 +564,12 @@ NexusSet* NetPDelay::nex_input(bool rem_out, bool search_funcs) const
return result;
}
NexusSet* NetRepeat::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetRepeat::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
NexusSet*result = expr_->nex_input(rem_out, always_sens);
if (statement_) {
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -541,7 +580,7 @@ NexusSet* NetRepeat::nex_input(bool rem_out, bool search_funcs) const
/*
* The $display, etc. system tasks can have NULL arguments.
*/
NexusSet* NetSTask::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetSTask::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = new NexusSet;
@ -549,7 +588,7 @@ NexusSet* NetSTask::nex_input(bool rem_out, bool search_funcs) const
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
if (parms_[idx]) {
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}
@ -568,12 +607,12 @@ NexusSet* NetUTask::nex_input(bool, bool) const
return new NexusSet;
}
NexusSet* NetWhile::nex_input(bool rem_out, bool search_funcs) const
NexusSet* NetWhile::nex_input(bool rem_out, bool always_sens) const
{
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
NexusSet*result = cond_->nex_input(rem_out, always_sens);
if (proc_) {
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
NexusSet*tmp = proc_->nex_input(rem_out, always_sens);
result->add(*tmp);
delete tmp;
}

View File

@ -2054,7 +2054,7 @@ class NetExpr : public LineInfo {
// Get the Nexus that are the input to this
// expression. Normally this descends down to the reference to
// a signal that reads from its input.
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const =0;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const =0;
// Return a version of myself that is structural. This is used
// for converting expressions to gates. The arguments are:
@ -2097,7 +2097,7 @@ class NetEArrayPattern : public NetExpr {
void dump(ostream&) const;
NetEArrayPattern* dup_expr() const;
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
private:
std::vector<NetExpr*> items_;
@ -2130,7 +2130,7 @@ class NetEConst : public NetExpr {
virtual NetEConst* dup_expr() const;
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual NetExpr*evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&ctx) const;
@ -2202,7 +2202,7 @@ class NetECReal : public NetExpr {
virtual NetECReal* dup_expr() const;
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual NetExpr*evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&ctx) const;
@ -2646,7 +2646,7 @@ class NetProc : public virtual LineInfo {
// Find the nexa that are input by the statement. This is used
// for example by @* to find the inputs to the process for the
// sensitivity list.
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
// Find the nexa that are set by the statement. Add the output
// values to the set passed as a parameter.
@ -2754,7 +2754,7 @@ class NetAlloc : public NetProc {
const NetScope* scope() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -2863,7 +2863,7 @@ class NetAssign_ {
// being outputs. For example foo[idx] = ... is the l-value
// (NetAssign_ object) with a foo l-value and the input
// expression idx.
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
// Figuring out nex_output to process ultimately comes down to
// this method.
@ -2911,7 +2911,7 @@ class NetAssignBase : public NetProc {
void set_delay(NetExpr*);
const NetExpr* get_delay() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&o);
@ -3029,7 +3029,7 @@ class NetBlock : public NetProc {
// for sequential blocks.
void emit_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
@ -3073,7 +3073,7 @@ class NetCase : public NetProc {
inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
inline const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&out);
bool synth_async(Design*des, NetScope*scope,
@ -3153,7 +3153,7 @@ class NetCondit : public NetProc {
bool emit_recurse_if(struct target_t*) const;
bool emit_recurse_else(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&o);
bool is_asynchronous();
@ -3244,7 +3244,7 @@ class NetDisable : public NetProc {
const NetScope*target() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3275,7 +3275,7 @@ class NetDoWhile : public NetProc {
void emit_proc_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3409,7 +3409,7 @@ class NetEvTrig : public NetProc {
const NetEvent*event() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3451,7 +3451,7 @@ class NetEvWait : public NetProc {
// process? This method checks.
virtual bool is_synchronous();
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&out);
virtual bool synth_async(Design*des, NetScope*scope,
@ -3537,7 +3537,7 @@ class NetForever : public NetProc {
void emit_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3561,7 +3561,7 @@ class NetForLoop : public NetProc {
void emit_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3599,7 +3599,7 @@ class NetFree : public NetProc {
const NetScope* scope() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3664,7 +3664,7 @@ class NetPDelay : public NetProc {
uint64_t delay() const;
const NetExpr*expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
@ -3692,7 +3692,7 @@ class NetRepeat : public NetProc {
const NetExpr*expr() const;
void emit_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3746,7 +3746,7 @@ class NetSTask : public NetProc {
const NetExpr* parm(unsigned idx) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3807,7 +3807,7 @@ class NetELast : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetELast*dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
private:
NetNet*sig_;
@ -3836,7 +3836,7 @@ class NetEUFunc : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEUFunc*dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual NetExpr* eval_tree();
virtual NetExpr*evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&ctx) const;
@ -3872,7 +3872,7 @@ class NetEAccess : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEAccess*dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
private:
NetBranch*branch_;
@ -3894,7 +3894,7 @@ class NetUTask : public NetProc {
const NetScope* task() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -3920,7 +3920,7 @@ class NetWhile : public NetProc {
void emit_proc_recurse(struct target_t*) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void nex_output(NexusSet&);
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -4064,7 +4064,7 @@ class NetEBinary : public NetExpr {
virtual NetExpr* eval_tree();
virtual NetExpr* evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&ctx) const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@ -4318,7 +4318,7 @@ class NetEConcat : public NetExpr {
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual bool has_width() const;
virtual NetEConcat* dup_expr() const;
virtual NetEConst* eval_tree();
@ -4366,7 +4366,7 @@ class NetESelect : public NetExpr {
// sub-expression.
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEConst* eval_tree();
@ -4395,7 +4395,7 @@ class NetEEvent : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEEvent* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4418,7 +4418,7 @@ class NetENetenum : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetENetenum* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4442,7 +4442,7 @@ class NetENew : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetENew* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4464,7 +4464,7 @@ class NetENull : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetENull* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
};
@ -4490,7 +4490,7 @@ class NetEProperty : public NetExpr {
ivl_variable_type_t expr_type() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEProperty* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4515,7 +4515,7 @@ class NetEScope : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEScope* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4549,7 +4549,7 @@ class NetESFunc : public NetExpr {
map<perm_string,LocalVar>&ctx) const;
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual const netenum_t* enumeration() const;
virtual void dump(ostream&) const;
@ -4683,7 +4683,7 @@ class NetEShallowCopy : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEShallowCopy* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void dump(ostream&os) const;
@ -4715,7 +4715,7 @@ class NetETernary : public NetExpr {
virtual NetExpr*evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&ctx) const;
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
@ -4770,7 +4770,7 @@ class NetEUnary : public NetExpr {
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@ -4846,7 +4846,9 @@ class NetESignal : public NetExpr {
virtual NetESignal* dup_expr() const;
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
NexusSet* nex_input(bool rem_out = true, bool always_sens = false) const;
NexusSet* nex_input_base(bool rem_out, bool always_sens,
unsigned base, unsigned width) const;
const netenum_t*enumeration() const;
virtual NetExpr*evaluate_function(const LineInfo&loc,

12
parse.y
View File

@ -864,7 +864,7 @@ class_item /* IEEE1800-2005: A.1.8 */
current_function = 0;
}
/* Class properties... */
/* IEEE1800-2017: A.1.9 Class items: Class properties... */
| property_qualifier_opt data_type list_of_variable_decl_assignments ';'
{ pform_class_property(@2, $1, $2, $3); }
@ -872,7 +872,15 @@ class_item /* IEEE1800-2005: A.1.8 */
| K_const class_item_qualifier_opt data_type list_of_variable_decl_assignments ';'
{ pform_class_property(@1, $2 | property_qualifier_t::make_const(), $3, $4); }
/* Class methods... */
/* IEEEE1800-2017: A.1.9 Class items: class_item ::= { property_qualifier} data_declaration */
| property_qualifier_opt K_typedef data_type IDENTIFIER dimensions_opt ';'
{ perm_string name = lex_strings.make($4);
delete[]$4;
pform_set_typedef(name, $3, $5);
}
/* IEEE1800-1017: A.1.9 Class items: Class methods... */
| method_qualifier_opt task_declaration
{ /* The task_declaration rule puts this into the class */ }

View File

@ -67,6 +67,10 @@ void pform_class_property(const struct vlltype&loc,
{
assert(pform_cur_class);
if (enum_type_t*enum_set = dynamic_cast<enum_type_t*>(data_type)) {
pform_cur_class->enum_sets .insert(enum_set);
}
// Add the non-static properties to the class type
// object. Unwind the list of names to make a map of name to
// type.

View File

@ -58,7 +58,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.cc)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -61,7 +61,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -56,7 +56,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -55,7 +55,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -61,7 +61,8 @@ distclean: clean
rm -f stamp-pcb_config-h pcb_config.h
cppcheck: $(O:.o=.cc)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
-UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \

View File

@ -1,5 +1,5 @@
%pure-parser
%define api.pure
%parse-param {const char*file_path}
%{

View File

@ -56,7 +56,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.cc)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -57,7 +57,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -55,7 +55,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -60,7 +60,8 @@ distclean: clean
rm -f stamp-vhdl_config-h vhdl_config.h
cppcheck: $(O:.o=.cc)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -56,7 +56,8 @@ distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2017 Cary R. (cygcary@yahoo.com)
* Copyright (C) 2011-2019 Cary R. (cygcary@yahoo.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -90,8 +90,10 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
/* If this is an always_comb/latch then we need to add a trigger to
* get the correct functionality. */
if (ivl_stmt_needs_t0_trigger(stmt)) {
assert(first == 0);
fprintf(vlog_out, " or IVL_top_priv_module.IVL_T0_trigger_event");
if (! first) {
fprintf(vlog_out, " or ");
}
fprintf(vlog_out, "IVL_top_priv_module.IVL_T0_trigger_event");
need_ivl_top_module = 1;
};
}

View File

@ -68,7 +68,8 @@ distclean: clean
rm -f stamp-vvp_config-h vvp_config.h
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status

View File

@ -1654,7 +1654,10 @@ static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
show_stmt_file_line(net, "Event wait (@) statement.");
if (ivl_stmt_nevent(net) == 1) {
if (ivl_stmt_nevent(net) == 0) {
assert(ivl_stmt_needs_t0_trigger(net) == 1);
fprintf(vvp_out, " %%wait E_0x0;\n");
} else if (ivl_stmt_nevent(net) == 1) {
ivl_event_t ev = ivl_stmt_events(net, 0);
if (ivl_stmt_needs_t0_trigger(net)) {
fprintf(vvp_out, "Ewait_%u .event/or E_%p, E_0x0;\n",

View File

@ -85,7 +85,7 @@ distclean: clean
rm -f stamp-vhdlpp_config-h vhdlpp_config.h
cppcheck: $(O:.o=.cc)
cppcheck --enable=all -f \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
-UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \

View File

@ -1,5 +1,5 @@
%pure-parser
%define api.pure
%lex-param { yyscan_t yyscanner }
%parse-param {yyscan_t yyscanner }
%parse-param {const char*file_path}

View File

@ -101,7 +101,8 @@ distclean: clean
# The -U flag is used to skip checking paths that depend on that define having
# an explicit value (i.e. the define is expected to be real code).
cppcheck: $(O:.o=.c) $(OPP:.o=.cc) $(M:.o=.c) $(V:.o=.c)
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
-UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \

View File

@ -42,6 +42,7 @@
#include "fstapi.h"
#include "fastlz.h"
#include "lz4.h"
#include <errno.h>
#ifndef HAVE_LIBPTHREAD
#undef FST_WRITER_PARALLEL
@ -952,6 +953,17 @@ fflush(xc->handle);
/*
* mmap functions
*/
static void fstWriterMmapSanity(void *pnt, const char *file, int line, const char *usage)
{
if(pnt == MAP_FAILED)
{
fprintf(stderr, "fstMmap() assigned to %s failed: errno: %d, file %s, line %d.\n", usage, errno, file, line);
perror("Why");
pnt = NULL;
}
}
static void fstWriterCreateMmaps(struct fstWriterContext *xc)
{
off_t curpos = ftello(xc->handle);
@ -974,12 +986,20 @@ fflush(xc->handle);
if(!xc->valpos_mem)
{
fflush(xc->valpos_handle);
xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0);
errno = 0;
if(xc->maxhandle)
{
fstWriterMmapSanity(xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0), __FILE__, __LINE__, "xc->valpos_mem");
}
}
if(!xc->curval_mem)
{
fflush(xc->curval_handle);
xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0);
errno = 0;
if(xc->maxvalpos)
{
fstWriterMmapSanity(xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0), __FILE__, __LINE__, "xc->curval_handle");
}
}
}
@ -1682,7 +1702,8 @@ fflush(xc->tchn_handle);
tlen = ftello(xc->tchn_handle);
fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0);
errno = 0;
fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0), __FILE__, __LINE__, "tmem");
if(tmem)
{
unsigned long destlen = tlen;
@ -1874,7 +1895,7 @@ if(xc)
if(xc && !xc->already_in_close && !xc->already_in_flush)
{
unsigned char *tmem;
unsigned char *tmem = NULL;
off_t fixup_offs, tlen, hlen;
xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */
@ -1912,7 +1933,12 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
/* write out geom section */
fflush(xc->geom_handle);
tlen = ftello(xc->geom_handle);
tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0);
errno = 0;
if(tlen)
{
fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0), __FILE__, __LINE__, "tmem");
}
if(tmem)
{
unsigned long destlen = tlen;
@ -2020,14 +2046,18 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
{
int lz4_maxlen;
unsigned char *mem;
unsigned char *hmem;
unsigned char *hmem = NULL;
int packed_len;
fflush(xc->handle);
lz4_maxlen = LZ4_compressBound(xc->hier_file_len);
mem = (unsigned char *)malloc(lz4_maxlen);
hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0);
errno = 0;
if(xc->hier_file_len)
{
fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem");
}
packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len);
fstMunmap(hmem, xc->hier_file_len);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2019 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
@ -332,9 +332,9 @@ static PLI_INT32 sys_readmem_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* Configure the readmem lexer */
if (strcmp(name,"$readmemb") == 0)
sys_readmem_start_file(file, 1, wwid, value.value.vector);
sys_readmem_start_file(callh, file, 1, wwid, value.value.vector);
else
sys_readmem_start_file(file, 0, wwid, value.value.vector);
sys_readmem_start_file(callh, file, 0, wwid, value.value.vector);
/*======================================== Read memory file */

View File

@ -1,7 +1,7 @@
#ifndef IVL_sys_readmem_lex_H
#define IVL_sys_readmem_lex_H
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2014,2019 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
@ -28,7 +28,7 @@
extern char *readmem_error_token;
extern void sys_readmem_start_file(FILE*in, int bin_flag,
extern void sys_readmem_start_file(vpiHandle callh, FILE*in, int bin_flag,
unsigned width, struct t_vpi_vecval*val);
extern int readmemlex(void);

View File

@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 1999-2017 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2017,2019 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
@ -57,6 +57,12 @@ char *readmem_error_token = 0;
<HEX,BIN>. { readmem_error_token = yytext; return MEM_ERROR; }
%%
/* The call_handle is the handle for the call to the $readmem()
system task. This is used for adding line numbers to warnings and
error messages. */
static vpiHandle call_handle = 0;
static int too_many_digits_warning = 0;
static unsigned word_width = 0;
static struct t_vpi_vecval*vecval = 0;
@ -134,6 +140,26 @@ static void make_hex_value(void)
word_max -= 32;
}
}
/* If there are more text digits then needed to fill the
memory word, count those digits and print a warning
message. Print that warning only once per call to
$readmemh() so that the user isn't flooded. */
int count_extra_digits = 0;
while (end > beg) {
end -= 1;
if (*end == '_') continue;
count_extra_digits += 1;
}
if (count_extra_digits && too_many_digits_warning==0) {
vpi_printf("WARNING: %s:%d: Excess hex digits (%d of '%s') while reading %d-bit words.\n",
vpi_get_str(vpiFile, call_handle),
vpi_get(vpiLineNo, call_handle),
count_extra_digits, beg,
word_width);
too_many_digits_warning += 1;
}
}
static void make_bin_value(void)
@ -181,11 +207,33 @@ static void make_bin_value(void)
word_max -= 32;
}
}
/* If there are more text digits then needed to fill the
memory word, count those digits and print a warning
message. Print that warning only once per call to
$readmem() so that the user isn't flooded. */
int count_extra_digits = 0;
while (end > beg) {
end -= 1;
if (*end == '_') continue;
count_extra_digits += 1;
}
if (count_extra_digits && too_many_digits_warning==0) {
vpi_printf("WARNING: %s:%d: Excess binary digits (%d of '%s') while reading %d-bit words.\n",
vpi_get_str(vpiFile, call_handle),
vpi_get(vpiLineNo, call_handle),
count_extra_digits, beg,
word_width);
too_many_digits_warning += 1;
}
}
void sys_readmem_start_file(FILE*in, int bin_flag,
void sys_readmem_start_file(vpiHandle callh, FILE*in, int bin_flag,
unsigned width, struct t_vpi_vecval *vv)
{
call_handle = callh;
too_many_digits_warning = 0;
yyrestart(in);
BEGIN(bin_flag? BIN : HEX);
word_width = width;

View File

@ -108,7 +108,8 @@ distclean: clean
rm -f stamp-config-h config.h
cppcheck: $(O:.o=.cc) libvpi.c draw_tt.c
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
--suppressions-list=$(srcdir)/cppcheck.sup \
-UMODULE_DIR1 -UMODULE_DIR2 -UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \

View File

@ -378,6 +378,8 @@ vpiHandle vvp_lookup_handle(const char*label)
vvp_net_t* vvp_net_lookup(const char*label)
{
static bool t0_trigger_generated = false;
/* First, look to see if the symbol is a vpi object of some
sort. If it is, then get the vvp_ipoint_t pointer out of
the vpiHandle. */
@ -425,6 +427,23 @@ vvp_net_t* vvp_net_lookup(const char*label)
/* Failing that, look for a general functor. */
vvp_net_t*tmp = lookup_functor_symbol(label);
// This is a special label used to create a T0 trigger for the
// always_comb/latch processes.
if (! t0_trigger_generated && (strcmp(label, "E_0x0") == 0)) {
// This should never happen, but if it does then the E_0x0
// event generation may need to be explicitly generated in
// the compiler output instead of implicitly in this code.
assert(! vpip_peek_current_scope()->is_automatic());
t0_trigger_generated = true;
// Create a local event with no name for the T0 trigger
compile_named_event(strdup(label), strcpy(new char [1],""), true);
tmp = vvp_net_lookup(label);
assert(tmp);
// Create a trigger for the T0 event.
vvp_net_ptr_t ptr (tmp, 0);
schedule_t0_trigger(ptr);
}
return tmp;
}
@ -481,7 +500,6 @@ struct vvp_net_resolv_list_s: public resolv_list_s {
bool vvp_net_resolv_list_s::resolve(bool mes)
{
static bool t0_trigger_generated = false;
vvp_net_t*tmp = vvp_net_lookup(label());
if (tmp) {
@ -490,25 +508,6 @@ bool vvp_net_resolv_list_s::resolve(bool mes)
return true;
}
// This is a special label used to create a T0 trigger for the
// always_comb/latch processes.
if (! t0_trigger_generated && (strcmp(label(), "E_0x0") == 0)) {
// This should never happen, but if it does then the E_0x0
// event generation may need to be explictly generated in
// the compiler output instead of implicitly in this code.
assert(! vpip_peek_current_scope()->is_automatic());
t0_trigger_generated = true;
// Create a local event with no name for the T0 trigger
compile_named_event(strdup(label()), strcpy(new char [1],""), true);
tmp = vvp_net_lookup(label());
assert(tmp);
tmp->link(port);
// Create a trigger for the T0 event.
vvp_net_ptr_t ptr (tmp, 0);
schedule_t0_trigger(ptr);
return true;
}
if (mes)
fprintf(stderr, "unresolved vvp_net reference: %s\n", label());