Add checks that verify an always statement has delay.
This patch adds check to determine if an always block has delay in it or not. If there is no delay a runtime infinite loop will occur. For the indeterminate case it will print a warning message if the new -Winfloop flag is given. This flag is not part of the -Wall check!
This commit is contained in:
parent
7b705a0212
commit
c38e8182c2
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __compiler_H
|
#ifndef __compiler_H
|
||||||
#define __compiler_H
|
#define __compiler_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2008 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
|
||||||
|
|
@ -76,6 +76,9 @@ extern bool warn_timescale;
|
||||||
/* Warn about legal but questionable module port bindings. */
|
/* Warn about legal but questionable module port bindings. */
|
||||||
extern bool warn_portbinding;
|
extern bool warn_portbinding;
|
||||||
|
|
||||||
|
/* Warn about structures that may have infinite loops. */
|
||||||
|
extern bool warn_inf_loop;
|
||||||
|
|
||||||
/* This is true if verbose output is requested. */
|
/* This is true if verbose output is requested. */
|
||||||
extern bool verbose_flag;
|
extern bool verbose_flag;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
VERSION = 0.8
|
VERSION = 0.9.devel
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.TH iverilog 1 "$Date: 2007/06/05 01:56:12 $" Version "$Date: 2007/06/05 01:56:12 $"
|
.TH iverilog 1 "April 22nd, 2008" Version "0.9.devel"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
iverilog - Icarus Verilog compiler
|
iverilog - Icarus Verilog compiler
|
||||||
|
|
||||||
|
|
@ -251,6 +251,21 @@ inherit timescale from another file. Both probably mean that
|
||||||
timescales are inconsistent, and simulation timing can be confusing
|
timescales are inconsistent, and simulation timing can be confusing
|
||||||
and dependent on compilation order.
|
and dependent on compilation order.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B infloop
|
||||||
|
This enables warnings for \fRalways\fP statements that may have runtime
|
||||||
|
infinite loops (has paths with no or zero delay). This class of warnings
|
||||||
|
is not included in \fB-Wall\fP and hence does not have a \fBno-\fP variant.
|
||||||
|
A fatal error message will always be printed when the compiler can
|
||||||
|
determine that there will definitely be an infinite loop (all paths have
|
||||||
|
no or zero delay).
|
||||||
|
|
||||||
|
When you suspect an always statement is producing a runtime infinite loop
|
||||||
|
use this flag to find the always statements that need to have their logic
|
||||||
|
verified. It is expected that many of the warnings will be false
|
||||||
|
positives, since the code treats the value of all variables and signals
|
||||||
|
as indeterminate.
|
||||||
|
|
||||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||||
a system function table file. A System function table file is used to
|
a system function table file. A System function table file is used to
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2008 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
|
||||||
|
|
@ -358,6 +358,11 @@ static void process_warning_switch(const char*name)
|
||||||
} else if (strcmp(name,"timescale") == 0) {
|
} else if (strcmp(name,"timescale") == 0) {
|
||||||
if (! strchr(warning_flags, 't'))
|
if (! strchr(warning_flags, 't'))
|
||||||
strcat(warning_flags, "t");
|
strcat(warning_flags, "t");
|
||||||
|
/* Since the infinite loop check is not part of 'all' it
|
||||||
|
* does not have a no- version. */
|
||||||
|
} else if (strcmp(name,"infloop") == 0) {
|
||||||
|
if (! strchr(warning_flags, 'l'))
|
||||||
|
strcat(warning_flags, "l");
|
||||||
} else if (strcmp(name,"no-implicit") == 0) {
|
} else if (strcmp(name,"no-implicit") == 0) {
|
||||||
char*cp = strchr(warning_flags, 'i');
|
char*cp = strchr(warning_flags, 'i');
|
||||||
if (cp) while (*cp) {
|
if (cp) while (*cp) {
|
||||||
|
|
@ -703,7 +708,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (version_flag || verbose_flag) {
|
if (version_flag || verbose_flag) {
|
||||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||||
printf("Copyright 1998-2007 Stephen Williams\n");
|
printf("Copyright 1998-2008 Stephen Williams\n");
|
||||||
puts(NOTICE);
|
puts(NOTICE);
|
||||||
|
|
||||||
if (version_flag)
|
if (version_flag)
|
||||||
|
|
@ -841,4 +846,3 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
23
elaborate.cc
23
elaborate.cc
|
|
@ -3277,6 +3277,29 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
|
||||||
verinum(1));
|
verinum(1));
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
/* If this is an always block and we have no or zero delay then
|
||||||
|
* a runtime infinite loop will happen. If we possible have some
|
||||||
|
* delay then print a warning that an infinite loop is possible.
|
||||||
|
*/
|
||||||
|
if (type() == PProcess::PR_ALWAYS) {
|
||||||
|
DelayType dly_type = top->statement()->delay_type();
|
||||||
|
|
||||||
|
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
||||||
|
cerr << get_fileline() << ": error: always statement"
|
||||||
|
<< " does not have any delay." << endl;
|
||||||
|
cerr << get_fileline() << ": : A runtime infinite"
|
||||||
|
<< " loop will occur." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
||||||
|
cerr << get_fileline() << ": warning: always statement"
|
||||||
|
<< " may not have any delay." << endl;
|
||||||
|
cerr << get_fileline() << ": : A runtime infinite"
|
||||||
|
<< " loop may be possible." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
109
main.cc
109
main.cc
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
const char COPYRIGHT[] =
|
const char COPYRIGHT[] =
|
||||||
"Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)";
|
"Copyright (c) 1998-2008 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
|
||||||
|
|
@ -18,9 +18,6 @@ const char COPYRIGHT[] =
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: main.cc,v 1.95 2007/04/19 02:52:53 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
|
|
@ -113,6 +110,7 @@ FILE *depend_file = NULL;
|
||||||
bool warn_implicit = false;
|
bool warn_implicit = false;
|
||||||
bool warn_timescale = false;
|
bool warn_timescale = false;
|
||||||
bool warn_portbinding = false;
|
bool warn_portbinding = false;
|
||||||
|
bool warn_inf_loop = false;
|
||||||
|
|
||||||
bool error_implicit = false;
|
bool error_implicit = false;
|
||||||
|
|
||||||
|
|
@ -434,6 +432,9 @@ static void read_iconfig_file(const char*ipath)
|
||||||
case 'i':
|
case 'i':
|
||||||
warn_implicit = true;
|
warn_implicit = true;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
warn_inf_loop = true;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
warn_portbinding = true;
|
warn_portbinding = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -830,103 +831,3 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
return des? des->errors : 1;
|
return des? des->errors : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: main.cc,v $
|
|
||||||
* Revision 1.95 2007/04/19 02:52:53 steve
|
|
||||||
* Add support for -v flag in command file.
|
|
||||||
*
|
|
||||||
* Revision 1.94 2007/03/07 04:24:59 steve
|
|
||||||
* Make integer width controllable.
|
|
||||||
*
|
|
||||||
* Revision 1.93 2006/09/28 04:35:18 steve
|
|
||||||
* Support selective control of specify and xtypes features.
|
|
||||||
*
|
|
||||||
* Revision 1.92 2005/07/14 23:38:43 steve
|
|
||||||
* Display as version 0.9.devel
|
|
||||||
*
|
|
||||||
* Revision 1.91 2005/07/07 16:22:49 steve
|
|
||||||
* Generalize signals to carry types.
|
|
||||||
*
|
|
||||||
* Revision 1.90 2005/06/28 04:25:55 steve
|
|
||||||
* Remove reference to SystemVerilog.
|
|
||||||
*
|
|
||||||
* Revision 1.89 2005/04/24 23:44:02 steve
|
|
||||||
* Update DFF support to new data flow.
|
|
||||||
*
|
|
||||||
* Revision 1.88 2005/01/22 01:06:55 steve
|
|
||||||
* Change case compare from logic to an LPM node.
|
|
||||||
*
|
|
||||||
* Revision 1.87 2004/12/11 02:31:26 steve
|
|
||||||
* Rework of internals to carry vectors through nexus instead
|
|
||||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
|
||||||
* down this path.
|
|
||||||
*
|
|
||||||
* Revision 1.86 2004/10/04 01:10:53 steve
|
|
||||||
* Clean up spurious trailing white space.
|
|
||||||
*
|
|
||||||
* Revision 1.85 2004/09/25 01:58:44 steve
|
|
||||||
* Add a debug_elaborate flag
|
|
||||||
*
|
|
||||||
* Revision 1.84 2004/09/10 23:51:42 steve
|
|
||||||
* Fix the evaluation of constant ternary expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.83 2004/09/05 17:44:42 steve
|
|
||||||
* Add support for module instance arrays.
|
|
||||||
*
|
|
||||||
* Revision 1.82 2004/03/10 04:51:24 steve
|
|
||||||
* Add support for system function table files.
|
|
||||||
*
|
|
||||||
* Revision 1.81 2004/02/18 17:11:56 steve
|
|
||||||
* Use perm_strings for named langiage items.
|
|
||||||
*
|
|
||||||
* Revision 1.80 2004/02/15 00:19:29 steve
|
|
||||||
* Report elaboration errors without crashing.
|
|
||||||
*
|
|
||||||
* Revision 1.79 2003/11/26 01:37:14 steve
|
|
||||||
* Properly initialize vpi_module_list with system.
|
|
||||||
*
|
|
||||||
* Revision 1.78 2003/11/13 05:55:33 steve
|
|
||||||
* Move the DLL= flag to target config files.
|
|
||||||
*
|
|
||||||
* Revision 1.77 2003/11/13 04:09:49 steve
|
|
||||||
* Pass flags through the temporary config file.
|
|
||||||
*
|
|
||||||
* Revision 1.76 2003/11/13 03:10:38 steve
|
|
||||||
* ivl -F and -t flags are onpassed throught the -C file.
|
|
||||||
*
|
|
||||||
* Revision 1.75 2003/11/10 20:59:03 steve
|
|
||||||
* Design::get_flag returns const char* instead of string.
|
|
||||||
*
|
|
||||||
* Revision 1.74 2003/11/01 04:22:30 steve
|
|
||||||
* Accept functors in the config file.
|
|
||||||
*
|
|
||||||
* Revision 1.73 2003/10/26 22:43:42 steve
|
|
||||||
* Improve -V messages,
|
|
||||||
*
|
|
||||||
* Revision 1.72 2003/09/26 02:17:14 steve
|
|
||||||
* Delete pform when done with it.
|
|
||||||
*
|
|
||||||
* Revision 1.71 2003/09/25 00:25:14 steve
|
|
||||||
* Summary list of missing modules.
|
|
||||||
*
|
|
||||||
* Revision 1.70 2003/09/23 05:57:36 steve
|
|
||||||
* Pass -m flag from driver via iconfig file.
|
|
||||||
*
|
|
||||||
* Revision 1.69 2003/09/22 01:12:08 steve
|
|
||||||
* Pass more ivl arguments through the iconfig file.
|
|
||||||
*
|
|
||||||
* Revision 1.68 2003/06/20 00:53:19 steve
|
|
||||||
* Module attributes from the parser
|
|
||||||
* through to elaborated form.
|
|
||||||
*
|
|
||||||
* Revision 1.67 2003/04/24 05:25:27 steve
|
|
||||||
* Dump design even on errors.
|
|
||||||
*
|
|
||||||
* Revision 1.66 2003/03/01 06:25:30 steve
|
|
||||||
* Add the lex_strings string handler, and put
|
|
||||||
* scope names and system task/function names
|
|
||||||
* into this table. Also, permallocate event
|
|
||||||
* names from the beginning.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
|
||||||
204
netlist.cc
204
netlist.cc
|
|
@ -2417,3 +2417,207 @@ const NetProc*NetTaskDef::proc() const
|
||||||
{
|
{
|
||||||
return proc_;
|
return proc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the delay_type() functions. They are used to determine
|
||||||
|
* the type of delay for the given object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function implements the following table:
|
||||||
|
*
|
||||||
|
* in_A in_B out
|
||||||
|
* NO NO NO
|
||||||
|
* NO ZERO ZERO
|
||||||
|
* NO POS POS
|
||||||
|
* NO DEF POS
|
||||||
|
* ZERO NO ZERO
|
||||||
|
* ZERO ZERO ZERO
|
||||||
|
* ZERO POS POS
|
||||||
|
* ZERO DEF POS
|
||||||
|
* POS NO POS
|
||||||
|
* POS ZERO POS
|
||||||
|
* POS POS POS
|
||||||
|
* POS DEF POS
|
||||||
|
* DEF NO POS
|
||||||
|
* DEF ZERO POS
|
||||||
|
* DEF POS POS
|
||||||
|
* DEF DEF DEF
|
||||||
|
*
|
||||||
|
* It is used to combine two delay values.
|
||||||
|
*/
|
||||||
|
static DelayType combine_delays(const DelayType a, const DelayType b)
|
||||||
|
{
|
||||||
|
/* The default is POSSIBLE_DELAY. */
|
||||||
|
DelayType result = POSSIBLE_DELAY;
|
||||||
|
|
||||||
|
/* If both are no or zero delay then we return ZERO_DELAY. */
|
||||||
|
if ((a == NO_DELAY || a == ZERO_DELAY) &&
|
||||||
|
(b == NO_DELAY || b == ZERO_DELAY)) {
|
||||||
|
result = ZERO_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Except if both are no delay then we return NO_DELAY. */
|
||||||
|
if (a == NO_DELAY && b == NO_DELAY) {
|
||||||
|
result = NO_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If both are definite delay then we return DEFINITE_DELAY. */
|
||||||
|
if (a == DEFINITE_DELAY && b == DEFINITE_DELAY) {
|
||||||
|
result = DEFINITE_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is used to see what we can find out about the delay when it
|
||||||
|
* is given as an expression. We also use this for loop expressions.
|
||||||
|
*/
|
||||||
|
static DelayType delay_type_from_expr(const NetExpr*expr)
|
||||||
|
{
|
||||||
|
DelayType result = POSSIBLE_DELAY;
|
||||||
|
|
||||||
|
if (const NetEConst*e = dynamic_cast<const NetEConst*>(expr)) {
|
||||||
|
if (e->value().is_zero()) result = ZERO_DELAY;
|
||||||
|
else result = DEFINITE_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const NetECReal*e = dynamic_cast<const NetECReal*>(expr)) {
|
||||||
|
if (e->value().as_double() == 0.0) result = ZERO_DELAY;
|
||||||
|
else result = DEFINITE_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The looping structures can use the same basic code so put it here
|
||||||
|
* instead of duplicating it for each one (repeat and while).
|
||||||
|
*/
|
||||||
|
static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
|
||||||
|
{
|
||||||
|
DelayType result;
|
||||||
|
|
||||||
|
switch (delay_type_from_expr(expr)) {
|
||||||
|
/* We have a constant false expression so the body never runs. */
|
||||||
|
case ZERO_DELAY:
|
||||||
|
result = NO_DELAY;
|
||||||
|
break;
|
||||||
|
/* We have a constant true expression so the body always runs. */
|
||||||
|
case DEFINITE_DELAY:
|
||||||
|
result = proc->delay_type();
|
||||||
|
break;
|
||||||
|
/* We don't know if the body will run so reduce a DEFINITE_DELAY
|
||||||
|
* to a POSSIBLE_DELAY. All other stay the same. */
|
||||||
|
case POSSIBLE_DELAY:
|
||||||
|
result = combine_delays(NO_DELAY, proc->delay_type());
|
||||||
|
break;
|
||||||
|
/* This should never happen since delay_type_from_expr() only
|
||||||
|
* returns three different values. */
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The default object does not have any delay. */
|
||||||
|
DelayType NetProc::delay_type() const
|
||||||
|
{
|
||||||
|
return NO_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetBlock::delay_type() const
|
||||||
|
{
|
||||||
|
DelayType result = NO_DELAY;
|
||||||
|
|
||||||
|
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||||
|
DelayType dt = cur->delay_type();
|
||||||
|
if (dt > result) result = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetCase::delay_type() const
|
||||||
|
{
|
||||||
|
DelayType result = NO_DELAY;
|
||||||
|
bool def_stmt = false;
|
||||||
|
unsigned nstmts = nitems();
|
||||||
|
|
||||||
|
for (unsigned idx = 0; idx < nstmts; idx += 1) {
|
||||||
|
if (!expr(idx)) def_stmt = true;
|
||||||
|
if (idx == 0) {
|
||||||
|
result = stat(idx)->delay_type();
|
||||||
|
} else {
|
||||||
|
result = combine_delays(result, stat(idx)->delay_type());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't have a default statement we don't know for sure
|
||||||
|
* that we have a delay. */
|
||||||
|
if (!def_stmt) result = combine_delays(NO_DELAY, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetCondit::delay_type() const
|
||||||
|
{
|
||||||
|
DelayType result;
|
||||||
|
|
||||||
|
if (else_) {
|
||||||
|
result = combine_delays(if_->delay_type(), else_->delay_type());
|
||||||
|
} else {
|
||||||
|
result = if_->delay_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetEvWait::delay_type() const
|
||||||
|
{
|
||||||
|
return DEFINITE_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetForever::delay_type() const
|
||||||
|
{
|
||||||
|
return statement_->delay_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetPDelay::delay_type() const
|
||||||
|
{
|
||||||
|
if (expr_) {
|
||||||
|
return delay_type_from_expr(expr_);
|
||||||
|
} else {
|
||||||
|
if (delay() > 0) {
|
||||||
|
return DEFINITE_DELAY;
|
||||||
|
} else {
|
||||||
|
if (statement_) {
|
||||||
|
return statement_->delay_type();
|
||||||
|
} else {
|
||||||
|
return NO_DELAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetRepeat::delay_type() const
|
||||||
|
{
|
||||||
|
return get_loop_delay_type(expr_, statement_);
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetTaskDef::delay_type() const
|
||||||
|
{
|
||||||
|
return proc_->delay_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetUTask::delay_type() const
|
||||||
|
{
|
||||||
|
return task()->task_def()->delay_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayType NetWhile::delay_type() const
|
||||||
|
{
|
||||||
|
return get_loop_delay_type(cond_, proc_);
|
||||||
|
}
|
||||||
|
|
|
||||||
14
netlist.h
14
netlist.h
|
|
@ -1640,6 +1640,7 @@ class NetUDP : public NetNode {
|
||||||
PUdp *udp;
|
PUdp *udp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DelayType { NO_DELAY, ZERO_DELAY, POSSIBLE_DELAY, DEFINITE_DELAY };
|
||||||
|
|
||||||
/* =========
|
/* =========
|
||||||
* A process is a behavioral-model description. A process is a
|
* A process is a behavioral-model description. A process is a
|
||||||
|
|
@ -1689,6 +1690,9 @@ class NetProc : public virtual LineInfo {
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
// Recursively checks to see if there is delay in this element.
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class NetBlock;
|
friend class NetBlock;
|
||||||
NetProc*next_;
|
NetProc*next_;
|
||||||
|
|
@ -1896,6 +1900,7 @@ class NetBlock : public NetProc {
|
||||||
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*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Type type_;
|
const Type type_;
|
||||||
|
|
@ -1939,6 +1944,7 @@ class NetCase : public NetProc {
|
||||||
|
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -2012,6 +2018,7 @@ class NetCondit : public NetProc {
|
||||||
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*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr* expr_;
|
NetExpr* expr_;
|
||||||
|
|
@ -2229,6 +2236,7 @@ class NetEvWait : public NetProc {
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetProc*statement_;
|
NetProc*statement_;
|
||||||
|
|
@ -2296,6 +2304,7 @@ class NetForever : public NetProc {
|
||||||
virtual NexusSet* nex_input(bool rem_out = true);
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetProc*statement_;
|
NetProc*statement_;
|
||||||
|
|
@ -2368,6 +2377,7 @@ class NetPDelay : public NetProc {
|
||||||
|
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
bool emit_proc_recurse(struct target_t*) const;
|
bool emit_proc_recurse(struct target_t*) const;
|
||||||
|
|
||||||
|
|
@ -2392,6 +2402,7 @@ class NetRepeat : public NetProc {
|
||||||
virtual NexusSet* nex_input(bool rem_out = true);
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr*expr_;
|
NetExpr*expr_;
|
||||||
|
|
@ -2473,6 +2484,7 @@ class NetTaskDef {
|
||||||
NetNet*port(unsigned idx);
|
NetNet*port(unsigned idx);
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetScope*scope_;
|
NetScope*scope_;
|
||||||
|
|
@ -2541,6 +2553,7 @@ class NetUTask : public NetProc {
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetScope*task_;
|
NetScope*task_;
|
||||||
|
|
@ -2565,6 +2578,7 @@ class NetWhile : public NetProc {
|
||||||
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;
|
||||||
|
virtual DelayType delay_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr* cond_;
|
NetExpr* cond_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue