Fix some always_* issues
This commit is contained in:
parent
8a85d62ec7
commit
ba82ef463e
10
Statement.cc
10
Statement.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -294,20 +294,20 @@ PDoWhile::~PDoWhile()
|
||||||
}
|
}
|
||||||
|
|
||||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||||
: expr_(ee), statement_(0), search_funcs_(false)
|
: expr_(ee), statement_(0), always_sens_(false)
|
||||||
{
|
{
|
||||||
assert(expr_.count() > 0);
|
assert(expr_.count() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PEventStatement::PEventStatement(PEEvent*ee)
|
PEventStatement::PEventStatement(PEEvent*ee)
|
||||||
: expr_(1), statement_(0), search_funcs_(false)
|
: expr_(1), statement_(0), always_sens_(false)
|
||||||
{
|
{
|
||||||
expr_[0] = ee;
|
expr_[0] = ee;
|
||||||
}
|
}
|
||||||
|
|
||||||
PEventStatement::PEventStatement(bool search_funcs)
|
PEventStatement::PEventStatement(bool always_sens)
|
||||||
: statement_(0), search_funcs_(search_funcs)
|
: statement_(0), always_sens_(always_sens)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_Statement_H
|
#ifndef IVL_Statement_H
|
||||||
#define IVL_Statement_H
|
#define IVL_Statement_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -403,8 +403,8 @@ class PEventStatement : public Statement {
|
||||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||||
explicit PEventStatement(PEEvent*ee);
|
explicit PEventStatement(PEEvent*ee);
|
||||||
// Make an @* statement or make a special @* version with the items
|
// Make an @* statement or make a special @* version with the items
|
||||||
// from functions added and ouputs removed for always_comb/latch.
|
// from functions added and outputs removed for always_comb/latch.
|
||||||
explicit PEventStatement(bool search_funcs = false);
|
explicit PEventStatement(bool always_sens = false);
|
||||||
|
|
||||||
~PEventStatement();
|
~PEventStatement();
|
||||||
|
|
||||||
|
|
@ -430,7 +430,7 @@ class PEventStatement : public Statement {
|
||||||
private:
|
private:
|
||||||
svector<PEEvent*>expr_;
|
svector<PEEvent*>expr_;
|
||||||
Statement*statement_;
|
Statement*statement_;
|
||||||
bool search_funcs_;
|
bool always_sens_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream& operator << (ostream&o, const PEventStatement&obj);
|
ostream& operator << (ostream&o, const PEventStatement&obj);
|
||||||
|
|
|
||||||
115
elaborate.cc
115
elaborate.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2018 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
|
# include <iostream>
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <list>
|
# include <list>
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
|
|
@ -4221,13 +4222,13 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||||
* a value to change. */
|
* a value to change. */
|
||||||
extern bool synthesis; /* Synthesis flag from main.cc */
|
extern bool synthesis; /* Synthesis flag from main.cc */
|
||||||
bool rem_out = false;
|
bool rem_out = false;
|
||||||
if (synthesis || search_funcs_) {
|
if (synthesis || always_sens_) {
|
||||||
rem_out = true;
|
rem_out = true;
|
||||||
}
|
}
|
||||||
// If this is an always_comb/latch then we need an implicit T0
|
// If this is an always_comb/latch then we need an implicit T0
|
||||||
// trigger of the event expression.
|
// trigger of the event expression.
|
||||||
if (search_funcs_) wa->set_t0_trigger();
|
if (always_sens_) wa->set_t0_trigger();
|
||||||
NexusSet*nset = enet->nex_input(rem_out, search_funcs_);
|
NexusSet*nset = enet->nex_input(rem_out, always_sens_);
|
||||||
if (nset == 0) {
|
if (nset == 0) {
|
||||||
cerr << get_fileline() << ": error: Unable to elaborate:"
|
cerr << get_fileline() << ": error: Unable to elaborate:"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
@ -4237,6 +4238,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nset->size() == 0) {
|
if (nset->size() == 0) {
|
||||||
|
if (always_sens_) return wa;
|
||||||
|
|
||||||
cerr << get_fileline() << ": warning: @* found no "
|
cerr << get_fileline() << ": warning: @* found no "
|
||||||
"sensitivities so it will never trigger."
|
"sensitivities so it will never trigger."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
@ -4256,8 +4259,38 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||||
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
|
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
|
||||||
ev, NetEvProbe::ANYEDGE,
|
ev, NetEvProbe::ANYEDGE,
|
||||||
nset->size());
|
nset->size());
|
||||||
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1)
|
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));
|
connect(nset->at(idx).lnk, pr->pin(idx));
|
||||||
|
} else {
|
||||||
|
connect(nset->at(idx).lnk, pr->pin(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete nset;
|
delete nset;
|
||||||
des->add_node(pr);
|
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 Design::check_proc_delay() const
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
@ -6145,28 +6203,26 @@ bool Design::check_proc_delay() const
|
||||||
* a runtime infinite loop will happen. If we possibly have some
|
* a runtime infinite loop will happen. If we possibly have some
|
||||||
* delay then print a warning that an infinite loop is possible.
|
* delay then print a warning that an infinite loop is possible.
|
||||||
*/
|
*/
|
||||||
if ((pr->type() == IVL_PR_ALWAYS) ||
|
if (pr->type() == IVL_PR_ALWAYS) {
|
||||||
(pr->type() == IVL_PR_ALWAYS_COMB) ||
|
|
||||||
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
|
||||||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
|
||||||
DelayType dly_type = pr->statement()->delay_type();
|
DelayType dly_type = pr->statement()->delay_type();
|
||||||
|
|
||||||
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
||||||
cerr << pr->get_fileline() << ": error: always "
|
cerr << pr->get_fileline() << ": error: always "
|
||||||
<< " statement does not have any delay." << endl;
|
"process does not have any delay." << endl;
|
||||||
cerr << pr->get_fileline() << ": : A runtime "
|
cerr << pr->get_fileline() << ": : A runtime "
|
||||||
<< " infinite loop will occur." << endl;
|
"infinite loop will occur." << endl;
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
||||||
cerr << pr->get_fileline() << ": warning: always "
|
cerr << pr->get_fileline() << ": warning: always "
|
||||||
<< " statement may not have any delay." << endl;
|
"process may not have any delay." << endl;
|
||||||
cerr << pr->get_fileline() << ": : A runtime "
|
cerr << pr->get_fileline() << ": : A runtime "
|
||||||
<< "infinite loop may be possible." << endl;
|
<< "infinite loop may be possible." << endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The always_comb/ff/latch processes also have special
|
// The always_comb/ff/latch processes have special delay rules
|
||||||
// delay rules that need to be checked.
|
// that need to be checked.
|
||||||
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
|
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
|
||||||
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
||||||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
||||||
|
|
@ -6175,26 +6231,39 @@ bool Design::check_proc_delay() const
|
||||||
// The always_comb/latch processes have an event
|
// The always_comb/latch processes have an event
|
||||||
// control added automatically by the compiler.
|
// control added automatically by the compiler.
|
||||||
assert(pr->type() == IVL_PR_ALWAYS_FF);
|
assert(pr->type() == IVL_PR_ALWAYS_FF);
|
||||||
cerr << pr->get_fileline() << ": error: the "
|
cerr << pr->get_fileline() << ": error: the first "
|
||||||
<< "first statement of an always_ff must "
|
"statement of an always_ff process must be "
|
||||||
<< "be an event control." << endl;
|
"an event control statement." << endl;
|
||||||
result = true;
|
result = true;
|
||||||
} else if (wait->statement()->delay_type(true) != NO_DELAY) {
|
} else if (wait->statement()->delay_type(true) != NO_DELAY) {
|
||||||
cerr << pr->get_fileline() << ": error: there "
|
cerr << pr->get_fileline() << ": error: there must ";
|
||||||
<< "must ";
|
|
||||||
|
|
||||||
if (pr->type() == IVL_PR_ALWAYS_FF) {
|
if (pr->type() == IVL_PR_ALWAYS_FF) {
|
||||||
cerr << "only be a single event control "
|
cerr << "only be a single event control and "
|
||||||
<< "and no blocking delays in an "
|
"no blocking delays in an always_ff "
|
||||||
<< "always_ff process.";
|
"process.";
|
||||||
} else {
|
} else {
|
||||||
cerr << "be no event controls or blocking "
|
cerr << "be no event controls or blocking "
|
||||||
<< "delays in an always_comb/latch "
|
"delays in an " << pr->type()
|
||||||
<< " process.";
|
<< " process.";
|
||||||
}
|
}
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
167
net_nex_input.cc
167
net_nex_input.cc
|
|
@ -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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -43,13 +43,13 @@ NexusSet* NetProc::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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;
|
NexusSet*result = new NexusSet;
|
||||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||||
if (items_[idx]==0) continue;
|
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;
|
if (tmp == 0) continue;
|
||||||
|
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
|
|
@ -58,25 +58,25 @@ NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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*result = left_->nex_input(rem_out, always_sens);
|
||||||
NexusSet*tmp = right_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = right_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
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;
|
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) {
|
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||||
if (parms_[idx] == NULL) {
|
if (parms_[idx] == NULL) {
|
||||||
delete result;
|
delete result;
|
||||||
return new NexusSet;
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -136,14 +136,27 @@ NexusSet* NetEScope::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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*result = base_? base_->nex_input(rem_out, always_sens) : new NexusSet();
|
||||||
NexusSet*tmp = expr_->nex_input(rem_out, search_funcs);
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
/* See the comment for NetESignal below. */
|
/* 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 "
|
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||||
"bits in '" << *expr_ << "'." << endl;
|
"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.
|
* 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;
|
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) {
|
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||||
if (parms_[idx]) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +188,12 @@ NexusSet* NetEShallowCopy::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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,
|
* This is not what I would expect for the various selects (bit,
|
||||||
|
|
@ -183,55 +201,68 @@ NexusSet* NetESignal::nex_input(bool rem_out, bool search_funcs) const
|
||||||
* instead of building the appropriate select and then using it
|
* instead of building the appropriate select and then using it
|
||||||
* as the trigger. Other simulators also add everything.
|
* as the trigger. Other simulators also add everything.
|
||||||
*/
|
*/
|
||||||
|
bool const_select = false;
|
||||||
|
unsigned const_word = 0;
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
/* Local signals are not added to the sensitivity list. */
|
/* Local signals are not added to the sensitivity list. */
|
||||||
if (net_->local_flag()) return result;
|
if (net_->local_flag()) return result;
|
||||||
/* If we have an array index add it to the sensitivity list. */
|
/* If we have an array index add it to the sensitivity list. */
|
||||||
if (word_) {
|
if (word_) {
|
||||||
NexusSet*tmp;
|
NexusSet*tmp;
|
||||||
tmp = word_->nex_input(rem_out, search_funcs);
|
tmp = word_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
if (warn_sens_entire_arr) {
|
if (!always_sens && warn_sens_entire_arr) {
|
||||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||||
<< net_->unpacked_count() << " words in array '"
|
<< net_->unpacked_count() << " words in array '"
|
||||||
<< name() << "'." << endl;
|
<< 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)
|
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
||||||
result->add(net_->pin(idx).nexus(), 0, net_->vector_width());
|
result->add(net_->pin(idx).nexus(), base, width);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
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*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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
tmp = false_val_->nex_input(rem_out, search_funcs);
|
tmp = false_val_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEUFunc::nex_input(bool rem_out, bool search_funcs) const
|
NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens) const
|
||||||
{
|
{
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_funcs) {
|
if (always_sens) {
|
||||||
NetFuncDef*func = func_->func_def();
|
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
|
// Remove the function inputs
|
||||||
NexusSet*in = new NexusSet;
|
NexusSet*in = new NexusSet;
|
||||||
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
|
||||||
|
|
@ -249,9 +280,9 @@ NexusSet* NetEUFunc::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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
|
NexusSet* NetAlloc::nex_input(bool, bool) const
|
||||||
|
|
@ -259,18 +290,18 @@ NexusSet* NetAlloc::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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_);
|
assert(! nest_);
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
if (word_) {
|
if (word_) {
|
||||||
NexusSet*tmp = word_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = word_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
if (base_) {
|
if (base_) {
|
||||||
NexusSet*tmp = base_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = base_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -278,12 +309,12 @@ NexusSet* NetAssign_::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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;
|
NexusSet*result = new NexusSet;
|
||||||
// For the deassign and release statements there is no R-value.
|
// For the deassign and release statements there is no R-value.
|
||||||
if (rval_) {
|
if (rval_) {
|
||||||
NexusSet*tmp = rval_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = rval_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +323,7 @@ NexusSet* NetAssignBase::nex_input(bool rem_out, bool search_funcs) const
|
||||||
particular, index expressions are statement inputs as well,
|
particular, index expressions are statement inputs as well,
|
||||||
so should be addressed here. */
|
so should be addressed here. */
|
||||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -317,11 +348,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
|
* In this example, "t" should not be in the input set because it is
|
||||||
* used by the sequence as a temporary value.
|
* 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 (last_ == 0) return new NexusSet;
|
||||||
|
|
||||||
if (! search_funcs && (type_ != SEQU)) {
|
if (! always_sens && (type_ != SEQU)) {
|
||||||
cerr << get_fileline() << ": internal error: Sorry, "
|
cerr << get_fileline() << ": internal error: Sorry, "
|
||||||
<< "I don't know how to synthesize fork/join blocks."
|
<< "I don't know how to synthesize fork/join blocks."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
@ -336,7 +367,7 @@ NexusSet* NetBlock::nex_input(bool rem_out, bool search_funcs) const
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* Get the inputs for the current statement. */
|
/* 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. */
|
/* Add the current input set to the accumulated input set. */
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
|
|
@ -363,9 +394,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
|
* the inputs to all the guards, and the inputs to all the guarded
|
||||||
* statements.
|
* 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) {
|
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||||
|
|
||||||
|
|
@ -373,7 +404,7 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
|
||||||
if (items_[idx].statement == 0)
|
if (items_[idx].statement == 0)
|
||||||
continue;
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
|
|
@ -381,7 +412,7 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
|
||||||
case is special and is identified by a null
|
case is special and is identified by a null
|
||||||
guard. The default guard obviously has no input. */
|
guard. The default guard obviously has no input. */
|
||||||
if (items_[idx].guard) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -390,18 +421,18 @@ NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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) {
|
if (if_ != 0) {
|
||||||
NexusSet*tmp = if_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = if_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (else_ != 0) {
|
if (else_ != 0) {
|
||||||
NexusSet*tmp = else_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = else_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -414,12 +445,12 @@ NexusSet* NetDisable::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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_) {
|
if (proc_) {
|
||||||
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = proc_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -432,12 +463,12 @@ NexusSet* NetEvTrig::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
if (statement_) {
|
if (statement_) {
|
||||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -445,12 +476,12 @@ NexusSet* NetEvWait::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
if (statement_) {
|
if (statement_) {
|
||||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -458,30 +489,30 @@ NexusSet* NetForever::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
if (init_expr_) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (condition_) {
|
if (condition_) {
|
||||||
NexusSet*tmp = condition_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = condition_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step_statement_) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statement_) {
|
if (statement_) {
|
||||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -512,12 +543,12 @@ NexusSet* NetFree::nex_input(bool, bool) const
|
||||||
* include the input set of the <expr> because it does not affect the
|
* include the input set of the <expr> because it does not affect the
|
||||||
* result. The statement can be omitted.
|
* 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;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
if (statement_) {
|
if (statement_) {
|
||||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -525,12 +556,12 @@ NexusSet* NetPDelay::nex_input(bool rem_out, bool search_funcs) const
|
||||||
return result;
|
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_) {
|
if (statement_) {
|
||||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = statement_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -541,7 +572,7 @@ NexusSet* NetRepeat::nex_input(bool rem_out, bool search_funcs) const
|
||||||
/*
|
/*
|
||||||
* The $display, etc. system tasks can have NULL arguments.
|
* 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;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
||||||
|
|
@ -549,7 +580,7 @@ NexusSet* NetSTask::nex_input(bool rem_out, bool search_funcs) const
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||||
if (parms_[idx]) {
|
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);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -568,12 +599,12 @@ NexusSet* NetUTask::nex_input(bool, bool) const
|
||||||
return new NexusSet;
|
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_) {
|
if (proc_) {
|
||||||
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
|
NexusSet*tmp = proc_->nex_input(rem_out, always_sens);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
84
netlist.h
84
netlist.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_netlist_H
|
#ifndef IVL_netlist_H
|
||||||
#define IVL_netlist_H
|
#define IVL_netlist_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -2048,7 +2048,7 @@ class NetExpr : public LineInfo {
|
||||||
// Get the Nexus that are the input to this
|
// Get the Nexus that are the input to this
|
||||||
// expression. Normally this descends down to the reference to
|
// expression. Normally this descends down to the reference to
|
||||||
// a signal that reads from its input.
|
// 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
|
// Return a version of myself that is structural. This is used
|
||||||
// for converting expressions to gates. The arguments are:
|
// for converting expressions to gates. The arguments are:
|
||||||
|
|
@ -2091,7 +2091,7 @@ class NetEArrayPattern : public NetExpr {
|
||||||
void dump(ostream&) const;
|
void dump(ostream&) const;
|
||||||
|
|
||||||
NetEArrayPattern* dup_expr() 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:
|
private:
|
||||||
std::vector<NetExpr*> items_;
|
std::vector<NetExpr*> items_;
|
||||||
|
|
@ -2124,7 +2124,7 @@ class NetEConst : public NetExpr {
|
||||||
|
|
||||||
virtual NetEConst* dup_expr() const;
|
virtual NetEConst* dup_expr() const;
|
||||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
|
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,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
|
|
@ -2196,7 +2196,7 @@ class NetECReal : public NetExpr {
|
||||||
|
|
||||||
virtual NetECReal* dup_expr() const;
|
virtual NetECReal* dup_expr() const;
|
||||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
|
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,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
|
|
@ -2640,7 +2640,7 @@ class NetProc : public virtual LineInfo {
|
||||||
// Find the nexa that are input by the statement. This is used
|
// Find the nexa that are input by the statement. This is used
|
||||||
// for example by @* to find the inputs to the process for the
|
// for example by @* to find the inputs to the process for the
|
||||||
// sensitivity list.
|
// 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
|
// Find the nexa that are set by the statement. Add the output
|
||||||
// values to the set passed as a parameter.
|
// values to the set passed as a parameter.
|
||||||
|
|
@ -2748,7 +2748,7 @@ class NetAlloc : public NetProc {
|
||||||
|
|
||||||
const NetScope* scope() const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -2857,7 +2857,7 @@ class NetAssign_ {
|
||||||
// being outputs. For example foo[idx] = ... is the l-value
|
// being outputs. For example foo[idx] = ... is the l-value
|
||||||
// (NetAssign_ object) with a foo l-value and the input
|
// (NetAssign_ object) with a foo l-value and the input
|
||||||
// expression idx.
|
// 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
|
// Figuring out nex_output to process ultimately comes down to
|
||||||
// this method.
|
// this method.
|
||||||
|
|
@ -2905,7 +2905,7 @@ class NetAssignBase : public NetProc {
|
||||||
void set_delay(NetExpr*);
|
void set_delay(NetExpr*);
|
||||||
const NetExpr* get_delay() const;
|
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);
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3023,7 +3023,7 @@ class NetBlock : public NetProc {
|
||||||
// for sequential blocks.
|
// for sequential blocks.
|
||||||
void emit_recurse(struct target_t*) 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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
|
|
@ -3067,7 +3067,7 @@ class NetCase : public NetProc {
|
||||||
inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
|
inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
|
||||||
inline const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
|
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);
|
virtual void nex_output(NexusSet&out);
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
bool synth_async(Design*des, NetScope*scope,
|
||||||
|
|
@ -3147,7 +3147,7 @@ class NetCondit : public NetProc {
|
||||||
bool emit_recurse_if(struct target_t*) const;
|
bool emit_recurse_if(struct target_t*) const;
|
||||||
bool emit_recurse_else(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);
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
|
|
@ -3238,7 +3238,7 @@ class NetDisable : public NetProc {
|
||||||
|
|
||||||
const NetScope*target() const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3269,7 +3269,7 @@ class NetDoWhile : public NetProc {
|
||||||
|
|
||||||
void emit_proc_recurse(struct target_t*) const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3403,7 +3403,7 @@ class NetEvTrig : public NetProc {
|
||||||
|
|
||||||
const NetEvent*event() const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3445,7 +3445,7 @@ class NetEvWait : public NetProc {
|
||||||
// process? This method checks.
|
// process? This method checks.
|
||||||
virtual bool is_synchronous();
|
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 void nex_output(NexusSet&out);
|
||||||
|
|
||||||
virtual bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope,
|
||||||
|
|
@ -3531,7 +3531,7 @@ class NetForever : public NetProc {
|
||||||
|
|
||||||
void emit_recurse(struct target_t*) 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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3555,7 +3555,7 @@ class NetForLoop : public NetProc {
|
||||||
|
|
||||||
void emit_recurse(struct target_t*) 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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3593,7 +3593,7 @@ class NetFree : public NetProc {
|
||||||
|
|
||||||
const NetScope* scope() const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3658,7 +3658,7 @@ class NetPDelay : public NetProc {
|
||||||
uint64_t delay() const;
|
uint64_t delay() const;
|
||||||
const NetExpr*expr() 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 void nex_output(NexusSet&);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
|
|
@ -3686,7 +3686,7 @@ class NetRepeat : public NetProc {
|
||||||
const NetExpr*expr() const;
|
const NetExpr*expr() const;
|
||||||
void emit_recurse(struct target_t*) 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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3740,7 +3740,7 @@ class NetSTask : public NetProc {
|
||||||
|
|
||||||
const NetExpr* parm(unsigned idx) const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3801,7 +3801,7 @@ class NetELast : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetELast*dup_expr() 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:
|
private:
|
||||||
NetNet*sig_;
|
NetNet*sig_;
|
||||||
|
|
@ -3830,7 +3830,7 @@ class NetEUFunc : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEUFunc*dup_expr() 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* eval_tree();
|
||||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
|
|
@ -3866,7 +3866,7 @@ class NetEAccess : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEAccess*dup_expr() 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:
|
private:
|
||||||
NetBranch*branch_;
|
NetBranch*branch_;
|
||||||
|
|
@ -3888,7 +3888,7 @@ class NetUTask : public NetProc {
|
||||||
|
|
||||||
const NetScope* task() const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -3914,7 +3914,7 @@ class NetWhile : public NetProc {
|
||||||
|
|
||||||
void emit_proc_recurse(struct target_t*) const;
|
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 void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -4058,7 +4058,7 @@ class NetEBinary : public NetExpr {
|
||||||
virtual NetExpr* eval_tree();
|
virtual NetExpr* eval_tree();
|
||||||
virtual NetExpr* evaluate_function(const LineInfo&loc,
|
virtual NetExpr* evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
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 expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
@ -4312,7 +4312,7 @@ class NetEConcat : public NetExpr {
|
||||||
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
|
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
|
||||||
|
|
||||||
virtual ivl_variable_type_t expr_type() 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 bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual NetEConcat* dup_expr() const;
|
virtual NetEConcat* dup_expr() const;
|
||||||
virtual NetEConst* eval_tree();
|
virtual NetEConst* eval_tree();
|
||||||
|
|
@ -4360,7 +4360,7 @@ class NetESelect : public NetExpr {
|
||||||
// sub-expression.
|
// sub-expression.
|
||||||
virtual ivl_variable_type_t expr_type() 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 bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEConst* eval_tree();
|
virtual NetEConst* eval_tree();
|
||||||
|
|
@ -4389,7 +4389,7 @@ class NetEEvent : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEEvent* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4412,7 +4412,7 @@ class NetENetenum : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetENetenum* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4436,7 +4436,7 @@ class NetENew : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetENew* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4458,7 +4458,7 @@ class NetENull : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetENull* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
};
|
};
|
||||||
|
|
@ -4484,7 +4484,7 @@ class NetEProperty : public NetExpr {
|
||||||
ivl_variable_type_t expr_type() const;
|
ivl_variable_type_t expr_type() const;
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEProperty* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4509,7 +4509,7 @@ class NetEScope : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEScope* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4543,7 +4543,7 @@ class NetESFunc : public NetExpr {
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
|
|
||||||
virtual ivl_variable_type_t expr_type() 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 const netenum_t* enumeration() const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -4677,7 +4677,7 @@ class NetEShallowCopy : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEShallowCopy* dup_expr() 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;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -4709,7 +4709,7 @@ class NetETernary : public NetExpr {
|
||||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
map<perm_string,LocalVar>&ctx) const;
|
map<perm_string,LocalVar>&ctx) const;
|
||||||
virtual ivl_variable_type_t expr_type() 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 expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
|
|
@ -4764,7 +4764,7 @@ class NetEUnary : public NetExpr {
|
||||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
|
|
||||||
virtual ivl_variable_type_t expr_type() 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 expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -4840,7 +4840,9 @@ class NetESignal : public NetExpr {
|
||||||
|
|
||||||
virtual NetESignal* dup_expr() const;
|
virtual NetESignal* dup_expr() const;
|
||||||
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
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;
|
const netenum_t*enumeration() const;
|
||||||
|
|
||||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||||
|
|
|
||||||
|
|
@ -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
|
* 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
|
* 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
|
/* If this is an always_comb/latch then we need to add a trigger to
|
||||||
* get the correct functionality. */
|
* get the correct functionality. */
|
||||||
if (ivl_stmt_needs_t0_trigger(stmt)) {
|
if (ivl_stmt_needs_t0_trigger(stmt)) {
|
||||||
assert(first == 0);
|
if (! first) {
|
||||||
fprintf(vlog_out, " or IVL_top_priv_module.IVL_T0_trigger_event");
|
fprintf(vlog_out, " or ");
|
||||||
|
}
|
||||||
|
fprintf(vlog_out, "IVL_top_priv_module.IVL_T0_trigger_event");
|
||||||
need_ivl_top_module = 1;
|
need_ivl_top_module = 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.");
|
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);
|
ivl_event_t ev = ivl_stmt_events(net, 0);
|
||||||
if (ivl_stmt_needs_t0_trigger(net)) {
|
if (ivl_stmt_needs_t0_trigger(net)) {
|
||||||
fprintf(vvp_out, "Ewait_%u .event/or E_%p, E_0x0;\n",
|
fprintf(vvp_out, "Ewait_%u .event/or E_%p, E_0x0;\n",
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,8 @@ vpiHandle vvp_lookup_handle(const char*label)
|
||||||
|
|
||||||
vvp_net_t* vvp_net_lookup(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
|
/* 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
|
sort. If it is, then get the vvp_ipoint_t pointer out of
|
||||||
the vpiHandle. */
|
the vpiHandle. */
|
||||||
|
|
@ -425,6 +427,23 @@ vvp_net_t* vvp_net_lookup(const char*label)
|
||||||
/* Failing that, look for a general functor. */
|
/* Failing that, look for a general functor. */
|
||||||
vvp_net_t*tmp = lookup_functor_symbol(label);
|
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;
|
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)
|
bool vvp_net_resolv_list_s::resolve(bool mes)
|
||||||
{
|
{
|
||||||
static bool t0_trigger_generated = false;
|
|
||||||
vvp_net_t*tmp = vvp_net_lookup(label());
|
vvp_net_t*tmp = vvp_net_lookup(label());
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
|
|
@ -490,25 +508,6 @@ bool vvp_net_resolv_list_s::resolve(bool mes)
|
||||||
return true;
|
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)
|
if (mes)
|
||||||
fprintf(stderr, "unresolved vvp_net reference: %s\n", label());
|
fprintf(stderr, "unresolved vvp_net reference: %s\n", label());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue