mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 17:43:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d0dce3267 | ||
|
|
9e29625207 | ||
|
|
a767da4f3f | ||
|
|
7bd96c2876 | ||
|
|
70fd64dcd6 | ||
|
|
bb2822f4b5 | ||
|
|
ad21108b63 | ||
|
|
e6808a787c | ||
|
|
1fb2762725 | ||
|
|
cce55941d3 | ||
|
|
6c8d95e0e2 | ||
|
|
216a178b28 | ||
|
|
6594a54a95 | ||
|
|
a9a4cf061a | ||
|
|
b7f0e204cb | ||
|
|
e6a15f233b | ||
|
|
e0edb596ea | ||
|
|
f2fb77c15a | ||
|
|
772a3a97eb | ||
|
|
6c310836a1 | ||
|
|
75416a3016 | ||
|
|
ebef78a13e | ||
|
|
e71baca39b | ||
|
|
18eb210313 | ||
|
|
7d38a5e1f9 | ||
|
|
4386077e2d | ||
|
|
49dbfd2131 | ||
|
|
a80fce5ac1 | ||
|
|
891b981cab | ||
|
|
2dd87b8384 | ||
|
|
062eb85075 | ||
|
|
e1f6802f5f | ||
|
|
6cfcd50f12 |
@@ -3,6 +3,36 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.846 2013-03-09
|
||||
|
||||
** IEEE 1800-2012 is now the default language. This adds 4 new keywords
|
||||
and updates the svdpi.h and vpi_user.h header files.
|
||||
|
||||
*** Add --report-unoptflat, bug611. [Jeremy Bennett]
|
||||
|
||||
*** Add duplicate clock gate optimization, msg980. [Varun Koyyalagunta]
|
||||
Disabled unless -OD or -O3 used, please try it as may get some
|
||||
significant speedups.
|
||||
|
||||
*** Fix wrong dot resolution under inlining. [Art Stamness]
|
||||
|
||||
**** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander]
|
||||
|
||||
**** Support bind in $unit, bug602. [Ed Lander]
|
||||
|
||||
**** Support <number>'() sized casts, bug628. [Ed Lander]
|
||||
|
||||
**** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett]
|
||||
|
||||
**** Fix LITENDIAN on unpacked structures, bug614. [Wai Sum Mong]
|
||||
|
||||
**** Fix 32-bit OS VPI scan issue, bug615. [Jeremy Bennett, Rich Porter]
|
||||
|
||||
**** Fix opening a VerilatedVcdC file multiple times, msg1021. [Frederic Requin]
|
||||
|
||||
**** Fix UNOPTFLAT circular array bounds crossing, bug630. [Jie Xu]
|
||||
|
||||
|
||||
* Verilator 3.845 2013/02/04
|
||||
|
||||
*** Fix nested packed arrays and struct, bug600. [Jeremy Bennett]
|
||||
|
||||
+1
-1
@@ -1,6 +1,5 @@
|
||||
^CVS/
|
||||
/CVS/
|
||||
\.gdbinit$
|
||||
\.git/
|
||||
\.svn/
|
||||
\.(bak|old)/
|
||||
@@ -23,6 +22,7 @@
|
||||
src/Makefile$
|
||||
src/Makefile_obj$
|
||||
include/verilated.mk$
|
||||
test_regress/.gdbinit$
|
||||
config.cache$
|
||||
config.status$
|
||||
verilator.log
|
||||
|
||||
@@ -121,6 +121,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
include/vltstd/*.[chv]* \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
|
||||
src/.gdbinit \
|
||||
src/*.pl src/*.pod \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
|
||||
+40
-9
@@ -245,6 +245,7 @@ descriptions in the next sections for more information.
|
||||
+1364-2005ext+<ext> Use Verilog 2005 with file extension <ext>
|
||||
+1800-2005ext+<ext> Use SystemVerilog 2005 with file extension <ext>
|
||||
+1800-2009ext+<ext> Use SystemVerilog 2009 with file extension <ext>
|
||||
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
|
||||
--assert Enable all assertions
|
||||
--autoflush Flush streams after all $displays
|
||||
--bbox-sys Blackbox unknown $system calls
|
||||
@@ -308,12 +309,13 @@ descriptions in the next sections for more information.
|
||||
--private Debugging; see docs
|
||||
--psl Enable PSL parsing
|
||||
--public Debugging; see docs
|
||||
--report-unoptflat Extra diagnostics for UNOPTFLAT
|
||||
--savable Enable model save-restore
|
||||
--sc Create SystemC output
|
||||
--sp Create SystemPerl output
|
||||
--stats Create statistics file
|
||||
-sv Enable SystemVerilog parsing
|
||||
+systemverilogext+<ext> Synonym for +1800-2009ext+<ext>
|
||||
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
|
||||
--top-module <topname> Name of top level input module
|
||||
--trace Enable waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
@@ -373,6 +375,8 @@ with the --exe option.
|
||||
|
||||
=item +1800-2009ext+I<ext>
|
||||
|
||||
=item +1800-2012ext+I<ext>
|
||||
|
||||
Specifies the language standard to be used with a specific filename
|
||||
extension, I<ext>.
|
||||
|
||||
@@ -584,7 +588,7 @@ C<--debug> is equivalent to C<--debugi 4>).
|
||||
|
||||
Select the language to be used by default when first processing each
|
||||
Verilog file. The language value must be "1364-1995", "1364-2001",
|
||||
"1364-2005", "1800-2005" or "1800-2009".
|
||||
"1364-2005", "1800-2005", "1800-2009" or "1800-2012".
|
||||
|
||||
Any language associated with a particular file extension (see the various
|
||||
+I<lang>ext+ options) will be used in preference to the language specified
|
||||
@@ -597,7 +601,7 @@ legacy mixed language designs, the various +I<lang>ext+ options should be
|
||||
used.
|
||||
|
||||
If no language is specified, either by this flag or +I<lang>ext+ options,
|
||||
then the latest SystemVerilog language (IEEE 1800-2009) is used.
|
||||
then the latest SystemVerilog language (IEEE 1800-2012) is used.
|
||||
|
||||
=item +define+I<var>+I<value>
|
||||
|
||||
@@ -877,6 +881,27 @@ inlining. This will also turn off inlining as if all modules had a
|
||||
/*verilator public_module*/, unless the module specifically enabled it with
|
||||
/*verilator inline_module*/.
|
||||
|
||||
=item --report-unoptflat
|
||||
|
||||
Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the
|
||||
10 widest variables in the loop, and the 10 most fanned out variables in
|
||||
the loop. These are candidates for splitting into multiple variables to
|
||||
break the loop.
|
||||
|
||||
In addition produces a GraphViz DOT file of the entire strongly connected
|
||||
components within the source associated with each loop. This is produced
|
||||
irrespective of whether --dump-tree is set. Such graphs may help in
|
||||
analysing the problem, but can be very large indeed.
|
||||
|
||||
Various commands exist for viewing and manipulating DOT files. For example
|
||||
the I<dot> command can be used to convert a DOT file to a PDF for
|
||||
printing. For example:
|
||||
|
||||
dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot
|
||||
|
||||
will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT
|
||||
file.
|
||||
|
||||
=item --savable
|
||||
|
||||
Enable including save and restore functions in the generated model.
|
||||
@@ -918,7 +943,7 @@ compatibility with other simulators.
|
||||
|
||||
=item +systemverilogext+I<ext>
|
||||
|
||||
A synonym for C<+1800-2009ext+>I<ext>.
|
||||
A synonym for C<+1800-2012ext+>I<ext>.
|
||||
|
||||
=item --top-module I<topname>
|
||||
|
||||
@@ -1894,13 +1919,13 @@ It also supports .name and .* interconnection.
|
||||
Verilator partially supports concurrent assert and cover statements; see
|
||||
the enclosed coverage tests for the syntax which is allowed.
|
||||
|
||||
=head2 SystemVerilog 2009 (IEEE 1800-2009) Support
|
||||
=head2 SystemVerilog 2012 (IEEE 1800-2012) Support
|
||||
|
||||
Verilator implements a full SystemVerilog 2009 preprocessor, including
|
||||
Verilator implements a full SystemVerilog 2012 preprocessor, including
|
||||
function call-like preprocessor defines, default define arguments,
|
||||
`__FILE__, `__LINE__ and `undefineall.
|
||||
|
||||
Verilator currently has some support for SystemVerilog 2009 synthesis
|
||||
Verilator currently has some support for SystemVerilog synthesis
|
||||
constructs. As SystemVerilog features enter common usage they are added;
|
||||
please file a bug if a feature you need is missing.
|
||||
|
||||
@@ -2840,7 +2865,8 @@ correctly.
|
||||
=item DETECTARRAY
|
||||
|
||||
Error when Verilator tries to deal with a combinatorial loop that could not be
|
||||
flattened, and which involves a structure. This typically ocurrs when
|
||||
flattened, and which involves a datatype which Verilator cannot handle, such
|
||||
as an unpacked struct or a large unpacked array. This typically ocurrs when
|
||||
-Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below).
|
||||
|
||||
The solution is to break the loop, as described for UNOPTFLAT.
|
||||
@@ -2926,7 +2952,7 @@ simulators.
|
||||
|
||||
=item LITENDIAN
|
||||
|
||||
Warns that a vector is declared with little endian bit numbering
|
||||
Warns that a packed vector is declared with little endian bit numbering
|
||||
(i.e. [0:7]). Big endian bit numbering is now the overwhelming standard,
|
||||
and little numbering is now thus often due to simple oversight instead of
|
||||
intent.
|
||||
@@ -3145,6 +3171,11 @@ The UNOPTFLAT warning may also occur where outputs from a block of logic
|
||||
are independent, but occur in the same always block. To fix this, use the
|
||||
isolate_assignments meta comment described above.
|
||||
|
||||
To assist in resolving UNOPTFLAT, the option C<--report-unoptflat> can be
|
||||
used, which will provide suggestions for variables that can be split up,
|
||||
and a graph of all the nodes connected in the loop. See the L<Arguments>
|
||||
section for more details.
|
||||
|
||||
Ignoring this warning will only slow simulations, it will simulate
|
||||
correctly.
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.845 2013-02-04])
|
||||
AC_INIT([Verilator],[3.846 2013-03-09])
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||
|
||||
|
||||
@@ -157,6 +157,8 @@ void VerilatedVcd::openNext (bool incFilename) {
|
||||
|
||||
void VerilatedVcd::makeNameMap() {
|
||||
// Take signal information from each module and build m_namemapp
|
||||
deleteNameMap();
|
||||
m_nextCode = 1;
|
||||
m_namemapp = new NameMap;
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
|
||||
VerilatedVcdCallInfo *cip = m_callbacks[ent];
|
||||
@@ -183,15 +185,20 @@ void VerilatedVcd::makeNameMap() {
|
||||
newname += hiername;
|
||||
newmapp->insert(make_pair(newname,decl));
|
||||
}
|
||||
delete m_namemapp; m_namemapp=NULL;
|
||||
deleteNameMap();
|
||||
m_namemapp = newmapp;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::deleteNameMap() {
|
||||
if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; }
|
||||
}
|
||||
|
||||
VerilatedVcd::~VerilatedVcd() {
|
||||
close();
|
||||
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
|
||||
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
|
||||
deleteNameMap();
|
||||
// Remove from list of traces
|
||||
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
|
||||
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
|
||||
@@ -414,7 +421,7 @@ void VerilatedVcd::dumpHeader () {
|
||||
assert (m_modDepth==0);
|
||||
|
||||
// Reclaim storage
|
||||
delete m_namemapp;
|
||||
deleteNameMap();
|
||||
}
|
||||
|
||||
void VerilatedVcd::module (string name) {
|
||||
|
||||
@@ -57,7 +57,8 @@ typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluin
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcd
|
||||
/// Create a SystemPerl VCD dump
|
||||
/// Base class to create a Verilator VCD dump
|
||||
/// This is an internally used class - see VerilatedVcdC for what to call from applications
|
||||
|
||||
class VerilatedVcd {
|
||||
private:
|
||||
@@ -100,6 +101,7 @@ private:
|
||||
void closeErr();
|
||||
void openNext();
|
||||
void makeNameMap();
|
||||
void deleteNameMap();
|
||||
void printIndent (int levelchange);
|
||||
void printStr (const char* str);
|
||||
void printQuad (vluint64_t n);
|
||||
@@ -400,8 +402,12 @@ public:
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new VCD file
|
||||
/// This includes a complete header dump each time it is called,
|
||||
/// just as if this object was deleted and reconstructed.
|
||||
void open (const char* filename) { m_sptrace.open(filename); }
|
||||
/// Continue a VCD dump by rotating to a new file name
|
||||
/// The header is only in the first file created, this allows
|
||||
/// "cat" to be used to combine the header plus any number of data files.
|
||||
void openNext (bool incFilename=true) { m_sptrace.openNext(incFilename); }
|
||||
/// Set size in megabytes after which new file should be created
|
||||
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); };
|
||||
|
||||
@@ -839,7 +839,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
|
||||
case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned int)*((CData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned int)*((SData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u", (unsigned int)*((IData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%lu", (unsigned long)*((QData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return;
|
||||
default:
|
||||
strcpy(outStr, "-1");
|
||||
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits",
|
||||
@@ -1096,8 +1096,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
|
||||
}
|
||||
} else if (value_p->format == vpiDecStrVal) {
|
||||
char remainder[16];
|
||||
unsigned long val;
|
||||
int success = sscanf(value_p->value.str, "%30lu%15s", &val, remainder);
|
||||
unsigned long long val;
|
||||
int success = sscanf(value_p->value.str, "%30llu%15s", &val, remainder);
|
||||
if (success < 1) {
|
||||
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Parsing failed for '%s' as value %s for %s",
|
||||
VL_FUNC, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* This file contains the constant definitions, structure definitions,
|
||||
* and routine declarations used by SystemVerilog DPI.
|
||||
*
|
||||
* This file is from the SystemVerilog IEEE 1800-2009 Annex I.
|
||||
* This file is from the SystemVerilog IEEE 1800-2012 Annex I.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SVDPI
|
||||
@@ -35,18 +35,18 @@ typedef signed __int8 int8_t;
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Use to export a symbol from application */
|
||||
/* Use to import a symbol into dll */
|
||||
#ifndef DPI_DLLISPEC
|
||||
#if defined (_MSC_VER)
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLISPEC __declspec(dllimport)
|
||||
#else
|
||||
#define DPI_DLLISPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to import a symbol into application */
|
||||
/* Use to export a symbol from dll */
|
||||
#ifndef DPI_DLLESPEC
|
||||
#if defined (_MSC_VER)
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLESPEC __declspec(dllexport)
|
||||
#else
|
||||
#define DPI_DLLESPEC
|
||||
|
||||
+21
-21
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* vpi_user.h
|
||||
*
|
||||
* IEEE Std 1800 Programming Language Interface (PLI)
|
||||
* IEEE Std 1800-2012 Programming Language Interface (PLI)
|
||||
*
|
||||
* This file contains the constant definitions, structure definitions, and
|
||||
* routine declarations used by the SystemVerilog Verification Procedural
|
||||
@@ -61,9 +61,9 @@ typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
/* Use to export a symbol */
|
||||
/* Use to import a symbol */
|
||||
|
||||
#if WIN32
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#ifndef PLI_DLLISPEC
|
||||
#define PLI_DLLISPEC __declspec(dllimport)
|
||||
#define VPI_USER_DEFINED_DLLISPEC 1
|
||||
@@ -74,9 +74,9 @@ typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to import a symbol */
|
||||
/* Use to export a symbol */
|
||||
|
||||
#if WIN32
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#ifndef PLI_DLLESPEC
|
||||
#define PLI_DLLESPEC __declspec(dllexport)
|
||||
#define VPI_USER_DEFINED_DLLESPEC 1
|
||||
@@ -438,12 +438,12 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
#define vpiPlusOp 2 /* unary plus */
|
||||
#define vpiNotOp 3 /* unary not */
|
||||
#define vpiBitNegOp 4 /* bitwise negation */
|
||||
#define vpiUnaryAndOp 5 /* bitwise reduction and */
|
||||
#define vpiUnaryNandOp 6 /* bitwise reduction nand */
|
||||
#define vpiUnaryOrOp 7 /* bitwise reduction or */
|
||||
#define vpiUnaryNorOp 8 /* bitwise reduction nor */
|
||||
#define vpiUnaryXorOp 9 /* bitwise reduction xor */
|
||||
#define vpiUnaryXNorOp 10 /* bitwise reduction xnor */
|
||||
#define vpiUnaryAndOp 5 /* bitwise reduction AND */
|
||||
#define vpiUnaryNandOp 6 /* bitwise reduction NAND */
|
||||
#define vpiUnaryOrOp 7 /* bitwise reduction OR */
|
||||
#define vpiUnaryNorOp 8 /* bitwise reduction NOR */
|
||||
#define vpiUnaryXorOp 9 /* bitwise reduction XOR */
|
||||
#define vpiUnaryXNorOp 10 /* bitwise reduction XNOR */
|
||||
#define vpiSubOp 11 /* binary subtraction */
|
||||
#define vpiDivOp 12 /* binary division */
|
||||
#define vpiModOp 13 /* binary modulus */
|
||||
@@ -459,17 +459,17 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
#define vpiRShiftOp 23 /* binary right shift */
|
||||
#define vpiAddOp 24 /* binary addition */
|
||||
#define vpiMultOp 25 /* binary multiplication */
|
||||
#define vpiLogAndOp 26 /* binary logical and */
|
||||
#define vpiLogOrOp 27 /* binary logical or */
|
||||
#define vpiBitAndOp 28 /* binary bitwise and */
|
||||
#define vpiBitOrOp 29 /* binary bitwise or */
|
||||
#define vpiBitXorOp 30 /* binary bitwise xor */
|
||||
#define vpiBitXNorOp 31 /* binary bitwise xnor */
|
||||
#define vpiLogAndOp 26 /* binary logical AND */
|
||||
#define vpiLogOrOp 27 /* binary logical OR */
|
||||
#define vpiBitAndOp 28 /* binary bitwise AND */
|
||||
#define vpiBitOrOp 29 /* binary bitwise OR */
|
||||
#define vpiBitXorOp 30 /* binary bitwise XOR */
|
||||
#define vpiBitXNorOp 31 /* binary bitwise XNOR */
|
||||
#define vpiBitXnorOp vpiBitXNorOp /* added with 1364-2001 */
|
||||
#define vpiConditionOp 32 /* ternary conditional */
|
||||
#define vpiConcatOp 33 /* n-ary concatenation */
|
||||
#define vpiMultiConcatOp 34 /* repeated concatenation */
|
||||
#define vpiEventOrOp 35 /* event or */
|
||||
#define vpiEventOrOp 35 /* event OR */
|
||||
#define vpiNullOp 36 /* null operation */
|
||||
#define vpiListOp 37 /* list of expressions */
|
||||
#define vpiMinTypMaxOp 38 /* min:typ:max: delay expression */
|
||||
@@ -536,7 +536,7 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
same subtypes as vpiNetType */
|
||||
#define vpiSaveRestartID 62 /* unique ID for save/restart data */
|
||||
#define vpiSaveRestartLocation 63 /* name of save/restart data file */
|
||||
/* vpiValid,vpiValidTrue,vpiValidFalse are deprecated in 1800-2009 */
|
||||
/* vpiValid,vpiValidTrue,vpiValidFalse were deprecated in 1800-2009 */
|
||||
#define vpiValid 64 /* reentrant task/func frame or automatic
|
||||
variable is valid */
|
||||
#define vpiValidFalse 0
|
||||
@@ -661,7 +661,7 @@ typedef struct t_vpi_arrayvalue
|
||||
{
|
||||
PLI_INT32 *integers; /* integer values */
|
||||
PLI_INT16 *shortints; /* short integer values */
|
||||
PLI_INT16 *longints; /* long integer values */
|
||||
PLI_INT64 *longints; /* long integer values */
|
||||
PLI_BYTE8 *rawvals; /* 2/4-state vector elements */
|
||||
struct t_vpi_vecval *vectors; /* 4-state vector elements */
|
||||
struct t_vpi_time *times; /* time values */
|
||||
@@ -944,7 +944,7 @@ XXTERN PLI_INT32 vpi_compare_objects PROTO_PARAMS((vpiHandle object1,
|
||||
vpiHandle object2));
|
||||
XXTERN PLI_INT32 vpi_chk_error PROTO_PARAMS((p_vpi_error_info
|
||||
error_info_p));
|
||||
/* vpi_free_object() is deprecated in 1800-2009 */
|
||||
/* vpi_free_object() was deprecated in 1800-2009 */
|
||||
XXTERN PLI_INT32 vpi_free_object PROTO_PARAMS((vpiHandle object));
|
||||
XXTERN PLI_INT32 vpi_release_handle PROTO_PARAMS((vpiHandle object));
|
||||
XXTERN PLI_INT32 vpi_get_vlog_info PROTO_PARAMS((p_vpi_vlog_info
|
||||
|
||||
@@ -1136,6 +1136,7 @@ public:
|
||||
virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays
|
||||
virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations
|
||||
virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out
|
||||
virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
|
||||
virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out
|
||||
virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input
|
||||
virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed
|
||||
@@ -1389,6 +1390,7 @@ public:
|
||||
void addIfsp(AstNode* newp) { addOp2p(newp); }
|
||||
void addElsesp(AstNode* newp) { addOp3p(newp); }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isGateDedupable() const { return true; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
|
||||
+6
-6
@@ -695,18 +695,18 @@ void AstDisplay::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
//str<<" "<<displayType().ascii();
|
||||
}
|
||||
void AstJumpGo::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (labelp()) { labelp()->dump(str); }
|
||||
else { str<<"%Error:UNLINKED"; }
|
||||
}
|
||||
void AstEnumItemRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (itemp()) { itemp()->dump(str); }
|
||||
else { str<<"UNLINKED"; }
|
||||
}
|
||||
void AstJumpGo::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (labelp()) { labelp()->dump(str); }
|
||||
else { str<<"%Error:UNLINKED"; }
|
||||
}
|
||||
void AstPin::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
|
||||
|
||||
+31
-9
@@ -815,6 +815,7 @@ struct AstVar : public AstNode {
|
||||
// A variable (in/out/wire/reg/param) inside a module
|
||||
private:
|
||||
string m_name; // Name of variable
|
||||
string m_origName; // Original name before dot addition
|
||||
AstVarType m_varType; // Type of variable
|
||||
bool m_input:1; // Input or inout
|
||||
bool m_output:1; // Output or inout
|
||||
@@ -858,7 +859,7 @@ private:
|
||||
public:
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
, m_name(name), m_origName(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
childDTypep(dtp); // Only for parser
|
||||
@@ -866,7 +867,7 @@ public:
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
, m_name(name), m_origName(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
UASSERT(dtp,"AstVar created with no dtype");
|
||||
@@ -874,21 +875,21 @@ public:
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
, m_name(name), m_origName(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
, m_name(name), m_origName(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
, m_name(name), m_origName(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
if (examplep->childDTypep()) {
|
||||
@@ -898,10 +899,13 @@ public:
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Var, VAR)
|
||||
virtual void dump(ostream& str);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
AstVarType varType() const { return m_varType; } // * = Type of variable
|
||||
string origName() const { return m_origName; } // * = Original name
|
||||
void origName(const string& name) { m_origName = name; }
|
||||
AstVarType varType() const { return m_varType; } // * = Type of variable
|
||||
void varType(AstVarType type) { m_varType = type; }
|
||||
void varType2Out() { m_tristate=0; m_input=0; m_output=1; }
|
||||
void varType2In() { m_tristate=0; m_input=1; m_output=0; }
|
||||
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
||||
@@ -3180,6 +3184,20 @@ struct AstCast : public AstNode {
|
||||
AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); }
|
||||
};
|
||||
|
||||
struct AstCastSize : public AstNode {
|
||||
// Cast to specific size; signed/twostate inherited from lower element per IEEE
|
||||
AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp) : AstNode(fl) {
|
||||
setOp1p(lhsp); setOp2p(rhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(CastSize, CASTSIZE)
|
||||
virtual string emitVerilog() { return "((%r)'(%l))"; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
};
|
||||
|
||||
struct AstCCast : public AstNodeUniop {
|
||||
// Cast to C-based data type
|
||||
private:
|
||||
@@ -3999,7 +4017,7 @@ struct AstPattern : public AstNodeMath {
|
||||
// Parents: AstNodeAssign, AstPattern, ...
|
||||
// Children: expression, AstPattern, AstPatReplicate
|
||||
AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) {
|
||||
addNOp1p(itemsp);
|
||||
addNOp2p(itemsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Pattern, PATTERN)
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
@@ -4008,7 +4026,11 @@ struct AstPattern : public AstNodeMath {
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA; return "";}
|
||||
virtual bool cleanOut() {V3ERROR_NA; return "";}
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNode* itemsp() const { return op1p(); } // op1 = AstPatReplicate, AstPatMember, etc
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
|
||||
};
|
||||
struct AstPatMember : public AstNodeMath {
|
||||
// Verilog '{a} or '{a{b}}
|
||||
|
||||
+7
-6
@@ -87,15 +87,16 @@ private:
|
||||
AstVar* varp = vscp->varp();
|
||||
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
|
||||
AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType();
|
||||
AstStructDType *structp = varp->dtypeSkipRefp()->castStructDType();
|
||||
bool isArray = arrayp;
|
||||
int msb = isArray ? arrayp->msb() : 0;
|
||||
int lsb = isArray ? arrayp->lsb() : 0;
|
||||
if (isArray && ((msb - lsb + 1) > DETECTARRAY_MAX_INDEXES)) {
|
||||
bool isStruct = structp && structp->packed();
|
||||
int elements = isArray ? arrayp->elementsConst() : 1;
|
||||
if (isArray && (elements > DETECTARRAY_MAX_INDEXES)) {
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<<cvtToStr(DETECTARRAY_MAX_INDEXES)
|
||||
<<" array indexes (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()<<endl
|
||||
<<vscp->warnMore()
|
||||
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(msb-lsb+1));
|
||||
} else if (!isArray
|
||||
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(elements));
|
||||
} else if (!isArray && !isStruct
|
||||
&& !varp->dtypeSkipRefp()->castBasicDType()) {
|
||||
if (debug()) varp->dumpTree(cout,"-DETECTARRAY-");
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
@@ -109,7 +110,7 @@ private:
|
||||
m_topModp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
for (int index=lsb; index<=msb; ++index) {
|
||||
for (int index=0; index<elements; ++index) {
|
||||
AstChangeDet* changep
|
||||
= new AstChangeDet (vscp->fileline(),
|
||||
aselIfNeeded(isArray, index,
|
||||
|
||||
+319
-19
@@ -41,6 +41,7 @@
|
||||
#include "V3Graph.h"
|
||||
#include "V3Const.h"
|
||||
#include "V3Stats.h"
|
||||
#include "V3Hashed.h"
|
||||
|
||||
typedef list<AstNodeVarRef*> GateVarRefList;
|
||||
|
||||
@@ -55,21 +56,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
class GateLogicVertex;
|
||||
class GateVarVertex;
|
||||
class GateGraphBaseVisitor {
|
||||
public:
|
||||
virtual AstNUser* visit(GateLogicVertex* vertexp, AstNUser* vup=NULL) =0;
|
||||
virtual AstNUser* visit(GateVarVertex* vertexp, AstNUser* vup=NULL) =0;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Support classes
|
||||
|
||||
class GateEitherVertex : public V3GraphVertex {
|
||||
AstScope* m_scopep;
|
||||
bool m_reducible; // True if this node should be able to be eliminated
|
||||
bool m_dedupable; // True if this node should be able to be deduped
|
||||
bool m_consumed; // Output goes to something meaningful
|
||||
public:
|
||||
GateEitherVertex(V3Graph* graphp, AstScope* scopep)
|
||||
: V3GraphVertex(graphp), m_scopep(scopep), m_reducible(true), m_consumed(false) {}
|
||||
: V3GraphVertex(graphp), m_scopep(scopep), m_reducible(true), m_dedupable(true), m_consumed(false) {}
|
||||
virtual ~GateEitherVertex() {}
|
||||
// Accessors
|
||||
// ACCESSORS
|
||||
virtual string dotStyle() const { return m_consumed?"":"dotted"; }
|
||||
AstScope* scopep() const { return m_scopep; }
|
||||
bool reducible() const { return m_reducible; }
|
||||
bool dedupable() const { return m_dedupable; }
|
||||
void setConsumed(const char* consumedReason) {
|
||||
m_consumed = true;
|
||||
//UINFO(0,"\t\tSetConsumed "<<consumedReason<<" "<<this<<endl);
|
||||
@@ -79,6 +92,23 @@ public:
|
||||
m_reducible = false;
|
||||
//UINFO(0," NR: "<<nonReducibleReason<<" "<<name()<<endl);
|
||||
}
|
||||
void clearDedupable(const char* nonDedupableReason) {
|
||||
m_dedupable = false;
|
||||
//UINFO(0," ND: "<<nonDedupableReason<<" "<<name()<<endl);
|
||||
}
|
||||
void clearReducibleAndDedupable(const char* nonReducibleReason) {
|
||||
clearReducible(nonReducibleReason);
|
||||
clearDedupable(nonReducibleReason);
|
||||
}
|
||||
virtual AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) =0;
|
||||
// Returns only the result from the LAST vertex iterated over
|
||||
AstNUser* iterateInEdges(GateGraphBaseVisitor& v, AstNUser* vup=NULL) {
|
||||
AstNUser* retp = NULL;
|
||||
for (V3GraphEdge* edgep = inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
retp = dynamic_cast<GateEitherVertex*>(edgep->fromp())->accept(v, vup);
|
||||
}
|
||||
return retp;
|
||||
}
|
||||
};
|
||||
|
||||
class GateVarVertex : public GateEitherVertex {
|
||||
@@ -92,7 +122,7 @@ public:
|
||||
: GateEitherVertex(graphp, scopep), m_varScp(varScp), m_isTop(false)
|
||||
, m_isClock(false), m_rstSyncNodep(NULL), m_rstAsyncNodep(NULL) {}
|
||||
virtual ~GateVarVertex() {}
|
||||
// Accessors
|
||||
// ACCESSORS
|
||||
AstVarScope* varScp() const { return m_varScp; }
|
||||
virtual string name() const { return (cvtToStr((void*)m_varScp)+" "+varScp()->name()); }
|
||||
virtual string dotColor() const { return "blue"; }
|
||||
@@ -104,6 +134,16 @@ public:
|
||||
void rstSyncNodep(AstNode* nodep) { m_rstSyncNodep=nodep; }
|
||||
AstNode* rstAsyncNodep() const { return m_rstAsyncNodep; }
|
||||
void rstAsyncNodep(AstNode* nodep) { m_rstAsyncNodep=nodep; }
|
||||
// METHODS
|
||||
void propagateAttrClocksFrom(GateVarVertex* fromp) {
|
||||
// Propagate clock and general attribute onto this node
|
||||
varScp()->varp()->propagateAttrFrom(fromp->varScp()->varp());
|
||||
if (fromp->isClock()) {
|
||||
varScp()->varp()->usedClock(true);
|
||||
setIsClock();
|
||||
}
|
||||
}
|
||||
AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); }
|
||||
};
|
||||
|
||||
class GateLogicVertex : public GateEitherVertex {
|
||||
@@ -114,12 +154,13 @@ public:
|
||||
GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep, bool slow)
|
||||
: GateEitherVertex(graphp,scopep), m_nodep(nodep), m_activep(activep), m_slow(slow) {}
|
||||
virtual ~GateLogicVertex() {}
|
||||
// Accessors
|
||||
// ACCESSORS
|
||||
virtual string name() const { return (cvtToStr((void*)m_nodep)+"@"+scopep()->prettyName()); }
|
||||
virtual string dotColor() const { return "yellow"; }
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstActive* activep() const { return m_activep; }
|
||||
bool slow() const { return m_slow; }
|
||||
AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -134,6 +175,7 @@ private:
|
||||
// STATE
|
||||
bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks)
|
||||
AstNodeVarRef* m_lhsVarRef; // VarRef on lhs of assignment (what we're replacing)
|
||||
bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable
|
||||
|
||||
// METHODS
|
||||
void clearSimple(const char* because) {
|
||||
@@ -193,7 +235,7 @@ private:
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// *** Special iterator
|
||||
if (!m_isSimple) return; // Fastpath
|
||||
if (!nodep->isGateOptimizable()
|
||||
if (!(m_dedupe ? nodep->isGateDedupable() : nodep->isGateOptimizable())
|
||||
|| !nodep->isPure()
|
||||
|| nodep->isBrancher()) {
|
||||
UINFO(5, "Non optimizable type: "<<nodep<<endl);
|
||||
@@ -203,11 +245,12 @@ private:
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
GateOkVisitor(AstNode* nodep, bool buffersOnly) {
|
||||
GateOkVisitor(AstNode* nodep, bool buffersOnly, bool dedupe) {
|
||||
m_isSimple = true;
|
||||
m_substTreep = NULL;
|
||||
m_buffersOnly = buffersOnly;
|
||||
m_lhsVarRef = NULL;
|
||||
m_dedupe = dedupe;
|
||||
// Iterate
|
||||
nodep->accept(*this);
|
||||
// Check results
|
||||
@@ -258,6 +301,7 @@ private:
|
||||
bool m_inSlow; // Inside a slow structure
|
||||
V3Double0 m_statSigs; // Statistic tracking
|
||||
V3Double0 m_statRefs; // Statistic tracking
|
||||
V3Double0 m_statDedupLogic; // Statistic tracking
|
||||
|
||||
// METHODS
|
||||
void iterateNewStmt(AstNode* nodep, const char* nonReducibleReason, const char* consumeReason) {
|
||||
@@ -265,9 +309,10 @@ private:
|
||||
UINFO(4," STMT "<<nodep<<endl);
|
||||
// m_activep is null under AstCFunc's, that's ok.
|
||||
m_logicVertexp = new GateLogicVertex(&m_graph, m_scopep, nodep, m_activep, m_inSlow);
|
||||
if (!m_activeReducible) nonReducibleReason="Block Unreducible";
|
||||
if (nonReducibleReason) {
|
||||
m_logicVertexp->clearReducible(nonReducibleReason);
|
||||
m_logicVertexp->clearReducibleAndDedupable(nonReducibleReason);
|
||||
} else if (!m_activeReducible) {
|
||||
m_logicVertexp->clearReducible("Block Unreducible"); // Sequential logic is dedupable
|
||||
}
|
||||
if (consumeReason) m_logicVertexp->setConsumed(consumeReason);
|
||||
if (nodep->castSenItem()) m_logicVertexp->setConsumed("senItem");
|
||||
@@ -284,13 +329,13 @@ private:
|
||||
varscp->user1p(vertexp);
|
||||
if (varscp->varp()->isSigPublic()) {
|
||||
// Public signals shouldn't be changed, pli code might be messing with them
|
||||
vertexp->clearReducible("SigPublic");
|
||||
vertexp->clearReducibleAndDedupable("SigPublic");
|
||||
vertexp->setConsumed("SigPublic");
|
||||
}
|
||||
if (varscp->varp()->isIO() && varscp->scopep()->isTop()) {
|
||||
// We may need to convert to/from sysc/reg sigs
|
||||
vertexp->setIsTop();
|
||||
vertexp->clearReducible("isTop");
|
||||
vertexp->clearReducibleAndDedupable("isTop");
|
||||
vertexp->setConsumed("isTop");
|
||||
}
|
||||
if (varscp->varp()->isUsedClock()) vertexp->setConsumed("clock");
|
||||
@@ -305,6 +350,7 @@ private:
|
||||
void consumedMarkRecurse(GateEitherVertex* vertexp);
|
||||
void consumedMove();
|
||||
void replaceAssigns();
|
||||
void dedupe();
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
@@ -319,6 +365,8 @@ private:
|
||||
optimizeSignals(false);
|
||||
// Then propagate more complicated equations
|
||||
optimizeSignals(true);
|
||||
// Remove redundant logic
|
||||
if (v3Global.opt.oDedupe()) dedupe();
|
||||
// Warn
|
||||
warnSignals();
|
||||
consumedMark();
|
||||
@@ -443,6 +491,7 @@ private:
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
GateVisitor(AstNode* nodep) {
|
||||
AstNode::user1ClearTree();
|
||||
m_logicVertexp = NULL;
|
||||
m_scopep = NULL;
|
||||
m_modp = NULL;
|
||||
@@ -455,6 +504,7 @@ public:
|
||||
virtual ~GateVisitor() {
|
||||
V3Stats::addStat("Optimizations, Gate sigs deleted", m_statSigs);
|
||||
V3Stats::addStat("Optimizations, Gate inputs replaced", m_statRefs);
|
||||
V3Stats::addStat("Optimizations, Gate sigs deduped", m_statDedupLogic);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -464,7 +514,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->inEmpty()) {
|
||||
vvertexp->clearReducible("inEmpty"); // Can't deal with no sources
|
||||
vvertexp->clearReducibleAndDedupable("inEmpty"); // Can't deal with no sources
|
||||
if (!vvertexp->isTop() // Ok if top inputs are driverless
|
||||
&& !vvertexp->varScp()->varp()->valuep()
|
||||
&& !vvertexp->varScp()->varp()->isSigPublic()) {
|
||||
@@ -480,7 +530,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
}
|
||||
}
|
||||
else if (!vvertexp->inSize1()) {
|
||||
vvertexp->clearReducible("size!1"); // Can't deal with more than one src
|
||||
vvertexp->clearReducibleAndDedupable("size!1"); // Can't deal with more than one src
|
||||
}
|
||||
// Reduce it?
|
||||
if (!vvertexp->reducible()) {
|
||||
@@ -493,7 +543,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
AstNode* logicp = logicVertexp->nodep();
|
||||
if (logicVertexp->reducible()) {
|
||||
// Can we eliminate?
|
||||
GateOkVisitor okVisitor(logicp, vvertexp->isClock());
|
||||
GateOkVisitor okVisitor(logicp, vvertexp->isClock(), false);
|
||||
bool multiInputs = okVisitor.rhsVarRefs().size() > 1;
|
||||
// Was it ok?
|
||||
bool doit = okVisitor.isSimple();
|
||||
@@ -548,12 +598,8 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
UINFO(9," Point-to-new vertex "<<newvarscp<<endl);
|
||||
GateVarVertex* varvertexp = makeVarVertex(newvarscp);
|
||||
new V3GraphEdge(&m_graph, varvertexp, consumeVertexp, 1);
|
||||
newvarscp->varp()->propagateAttrFrom(vvertexp->varScp()->varp());
|
||||
if (vvertexp->isClock()) {
|
||||
// Propagate clock attribute onto generating node
|
||||
newvarscp->varp()->usedClock(true);
|
||||
varvertexp->setIsClock();
|
||||
}
|
||||
// Propagate clock attribute onto generating node
|
||||
varvertexp->propagateAttrClocksFrom(vvertexp);
|
||||
}
|
||||
// Remove the edge
|
||||
edgep->unlinkDelete(); edgep=NULL;
|
||||
@@ -725,6 +771,8 @@ private:
|
||||
// However a VARREF should point to the original as it's otherwise confusing
|
||||
// to throw warnings that point to a PIN rather than where the pin us used.
|
||||
if (substp->castVarRef()) substp->fileline(nodep->fileline());
|
||||
// Make the substp an rvalue like nodep. This facilitate the hashing in dedupe.
|
||||
if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false);
|
||||
nodep->replaceWith(substp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
@@ -756,6 +804,258 @@ void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode*
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Auxiliary hash class for GateDedupeVarVisitor
|
||||
|
||||
class GateDedupeHash : public V3HashedUserCheck {
|
||||
private:
|
||||
// NODE STATE
|
||||
// Ast*::user2p -> parent AstNodeAssign* for this rhsp
|
||||
// Ast*::user3p -> AstNode* checked in test for duplicate
|
||||
// Ast*::user5p -> AstNode* checked in test for duplicate
|
||||
// AstUser2InUse m_inuser2; (Allocated for use in GateVisitor)
|
||||
AstUser3InUse m_inuser3;
|
||||
AstUser5InUse m_inuser5;
|
||||
V3Hashed m_hashed; // Hash, contains rhs of assigns
|
||||
|
||||
void hash(AstNode* nodep) {
|
||||
// !NULL && the object is hashable
|
||||
if (nodep && !nodep->sameHash().isIllegal()) {
|
||||
m_hashed.hash(nodep);
|
||||
}
|
||||
}
|
||||
bool sameHash(AstNode* node1p, AstNode* node2p) {
|
||||
return (node1p && node2p
|
||||
&& !node1p->sameHash().isIllegal()
|
||||
&& !node2p->sameHash().isIllegal()
|
||||
&& m_hashed.sameNodes(node1p,node2p));
|
||||
}
|
||||
bool same(AstNUser* node1p, AstNUser* node2p) {
|
||||
return node1p == node2p || sameHash((AstNode*)node1p,(AstNode*)node2p);
|
||||
}
|
||||
public:
|
||||
bool check(AstNode* node1p,AstNode* node2p) {
|
||||
return same(node1p->user3p(),node2p->user3p()) && same(node1p->user5p(),node2p->user5p())
|
||||
&& node1p->user2p()->castNode()->type() == node2p->user2p()->castNode()->type()
|
||||
;
|
||||
}
|
||||
|
||||
AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) {
|
||||
AstNode *rhsp = assignp->rhsp();
|
||||
rhsp->user2p(assignp);
|
||||
rhsp->user3p(extra1p);
|
||||
rhsp->user5p(extra2p);
|
||||
|
||||
hash(extra1p);
|
||||
hash(extra2p);
|
||||
|
||||
V3Hashed::iterator inserted = m_hashed.hashAndInsert(rhsp);
|
||||
V3Hashed::iterator dupit = m_hashed.findDuplicate(rhsp, this);
|
||||
// Even though rhsp was just inserted, V3Hashed::findDuplicate doesn't
|
||||
// return anything in the hash that has the same pointer (V3Hashed.cpp::findDuplicate)
|
||||
// So dupit is either a different, duplicate rhsp, or the end of the hash.
|
||||
if (dupit != m_hashed.end()) {
|
||||
m_hashed.erase(inserted);
|
||||
return m_hashed.iteratorNodep(dupit)->user2p()->castNode()->castNodeAssign();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Have we seen the rhs of this assign before?
|
||||
|
||||
class GateDedupeVarVisitor : public GateBaseVisitor {
|
||||
// Given a node, it is visited to try to find the AstNodeAssign under it that can used for dedupe.
|
||||
// Right now, only the following node trees are supported for dedupe.
|
||||
// 1. AstNodeAssign
|
||||
// 2. AstAlways -> AstNodeAssign
|
||||
// (Note, the assign must also be the only node under the always)
|
||||
// 3. AstAlways -> AstNodeIf -> AstNodeAssign
|
||||
// (Note, the IF must be the only node under the always,
|
||||
// and the assign must be the only node under the if, other than the ifcond)
|
||||
// Any other ordering or node type, except for an AstComment, makes it not dedupable
|
||||
private:
|
||||
// STATE
|
||||
GateDedupeHash m_hash; // Hash used to find dupes of rhs of assign
|
||||
AstNodeAssign* m_assignp; // Assign found for dedupe
|
||||
AstNode* m_ifCondp; // IF condition that assign is under
|
||||
bool m_always; // Assign is under an always
|
||||
bool m_dedupable; // Determined the assign to be dedupable
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* assignp, AstNUser*) {
|
||||
if (m_dedupable) {
|
||||
// I think we could safely dedupe an always block with multiple non-blocking statements, but erring on side of caution here
|
||||
if (!m_assignp) {
|
||||
m_assignp = assignp;
|
||||
} else {
|
||||
m_dedupable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAlways* alwaysp, AstNUser*) {
|
||||
if (m_dedupable) {
|
||||
if (!m_always) {
|
||||
m_always = true;
|
||||
alwaysp->bodysp()->iterateAndNext(*this);
|
||||
} else {
|
||||
m_dedupable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ugly support for latches of the specific form -
|
||||
// always @(...)
|
||||
// if (...)
|
||||
// foo = ...; // or foo <= ...;
|
||||
virtual void visit(AstNodeIf* ifp, AstNUser*) {
|
||||
if (m_dedupable) {
|
||||
if (m_always && !m_ifCondp && !ifp->elsesp()) { //we're under an always, this is the first IF, and there's no else
|
||||
m_ifCondp = ifp->condp();
|
||||
ifp->ifsp()->iterateAndNext(*this);
|
||||
} else {
|
||||
m_dedupable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstComment*, AstNUser*) {} // NOP
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNode*, AstNUser*) {
|
||||
m_dedupable = false;
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
GateDedupeVarVisitor() {}
|
||||
// PUBLIC METHODS
|
||||
AstNodeVarRef* findDupe(AstNode* nodep, AstVarScope* consumerVarScopep, AstActive* activep) {
|
||||
m_assignp = NULL;
|
||||
m_ifCondp = NULL;
|
||||
m_always = false;
|
||||
m_dedupable = true;
|
||||
nodep->accept(*this);
|
||||
if (m_dedupable && m_assignp) {
|
||||
AstNode* lhsp = m_assignp->lhsp();
|
||||
// Possible todo, handle more complex lhs expressions
|
||||
if (AstNodeVarRef* lhsVarRefp = lhsp->castNodeVarRef()) {
|
||||
if (lhsVarRefp->varScopep() != consumerVarScopep) consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign");
|
||||
if (AstNodeAssign* dup = m_hash.hashAndFindDupe(m_assignp,activep,m_ifCondp)) {
|
||||
return (AstNodeVarRef*) dup->lhsp();
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Recurse through the graph, looking for duplicate expressions on the rhs of an assign
|
||||
|
||||
class GateDedupeGraphVisitor : public GateGraphBaseVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// AstVarScope::user2p -> bool: already visited
|
||||
// AstUser2InUse m_inuser2; (Allocated for use in GateVisitor)
|
||||
V3Double0 m_numDeduped; // Statistic tracking
|
||||
GateDedupeVarVisitor m_varVisitor; // Looks for a dupe of the logic
|
||||
|
||||
virtual AstNUser* visit(GateVarVertex *vvertexp, AstNUser*) {
|
||||
// Check that we haven't been here before
|
||||
if (vvertexp->varScp()->user2()) return NULL;
|
||||
vvertexp->varScp()->user2(true);
|
||||
|
||||
AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, (AstNUser*) vvertexp);
|
||||
|
||||
if (dupVarRefp && vvertexp->inSize1()) {
|
||||
V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
GateLogicVertex* lvertexp = (GateLogicVertex*)edgep->fromp();
|
||||
if (!vvertexp->dedupable()) vvertexp->varScp()->v3fatalSrc("GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
|
||||
GateOkVisitor okVisitor(lvertexp->nodep(), false, true);
|
||||
if (okVisitor.isSimple()) {
|
||||
AstVarScope* dupVarScopep = dupVarRefp->varScopep();
|
||||
GateVarVertex* dupVvertexp = (GateVarVertex*) (dupVarScopep->user1p());
|
||||
UINFO(4,"replacing " << vvertexp << " with " << dupVvertexp << endl);
|
||||
m_numDeduped++;
|
||||
// Replace all of this varvertex's consumers with dupVarRefp
|
||||
for (V3GraphEdge* outedgep = vvertexp->outBeginp();outedgep;) {
|
||||
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(outedgep->top());
|
||||
AstNode* consumerp = consumeVertexp->nodep();
|
||||
GateElimVisitor elimVisitor(consumerp,vvertexp->varScp(),dupVarRefp);
|
||||
outedgep = outedgep->relinkFromp(dupVvertexp);
|
||||
}
|
||||
|
||||
// Propogate attributes
|
||||
dupVvertexp->propagateAttrClocksFrom(vvertexp);
|
||||
|
||||
// Remove inputs links
|
||||
while (V3GraphEdge* inedgep = vvertexp->inBeginp()) {
|
||||
inedgep->unlinkDelete(); inedgep=NULL;
|
||||
}
|
||||
// replaceAssigns() does the deleteTree on lvertexNodep in a later step
|
||||
AstNode* lvertexNodep = lvertexp->nodep();
|
||||
lvertexNodep->unlinkFrBack();
|
||||
vvertexp->varScp()->valuep(lvertexNodep);
|
||||
lvertexNodep = NULL;
|
||||
vvertexp->user(true);
|
||||
lvertexp->user(true);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Returns a varref that has the same logic input
|
||||
virtual AstNUser* visit(GateLogicVertex* lvertexp, AstNUser* vup) {
|
||||
lvertexp->iterateInEdges(*this);
|
||||
|
||||
GateVarVertex* consumerVvertexpp = (GateVarVertex*) vup;
|
||||
if (lvertexp->dedupable() && consumerVvertexpp->dedupable()) {
|
||||
AstNode* nodep = lvertexp->nodep();
|
||||
AstVarScope* consumerVarScopep = consumerVvertexpp->varScp();
|
||||
// TODO: Doing a simple pointer comparison of activep won't work
|
||||
// optimally for statements under generated clocks. Statements under
|
||||
// different generated clocks will never compare as equal, even if the
|
||||
// generated clocks are deduped into one clock.
|
||||
AstActive* activep = lvertexp->activep();
|
||||
return (AstNUser*) m_varVisitor.findDupe(nodep, consumerVarScopep, activep);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
GateDedupeGraphVisitor() {}
|
||||
void dedupeTree(GateVarVertex* vvertexp) {
|
||||
vvertexp->accept(*this);
|
||||
}
|
||||
V3Double0 numDeduped() { return m_numDeduped; }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void GateVisitor::dedupe() {
|
||||
AstNode::user2ClearTree();
|
||||
GateDedupeGraphVisitor deduper;
|
||||
// Traverse starting from each of the clocks
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->isClock()) {
|
||||
deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Traverse starting from each of the outputs
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->isTop() && vvertexp->varScp()->varp()->isOutput()) {
|
||||
deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_statDedupLogic += deduper.numDeduped();
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Convert VARSCOPE(ASSIGN(default, VARREF)) to just VARSCOPE(default)
|
||||
|
||||
|
||||
+23
-5
@@ -39,9 +39,14 @@ int V3Graph::debug() { return max(V3Error::debugDefault(), s_debug); }
|
||||
//######################################################################
|
||||
// Vertices
|
||||
|
||||
V3GraphVertex::V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old)
|
||||
: m_fanout(old.m_fanout), m_color(old.m_color), m_rank(old.m_rank) {
|
||||
m_userp = NULL;
|
||||
verticesPushBack(graphp);
|
||||
}
|
||||
|
||||
V3GraphVertex::V3GraphVertex(V3Graph* graphp)
|
||||
: m_fanout(0), m_color(0), m_rank(0)
|
||||
{
|
||||
: m_fanout(0), m_color(0), m_rank(0) {
|
||||
m_userp = NULL;
|
||||
verticesPushBack(graphp);
|
||||
}
|
||||
@@ -125,9 +130,9 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp) {
|
||||
//######################################################################
|
||||
// Edges
|
||||
|
||||
V3GraphEdge::V3GraphEdge(V3Graph* graphp,
|
||||
V3GraphVertex* fromp, V3GraphVertex* top, int weight,
|
||||
bool cutable) {
|
||||
void V3GraphEdge::init(V3Graph* graphp,
|
||||
V3GraphVertex* fromp, V3GraphVertex* top, int weight,
|
||||
bool cutable) {
|
||||
UASSERT(fromp, "Null from pointer\n");
|
||||
UASSERT(top, "Null to pointer\n");
|
||||
m_fromp = fromp;
|
||||
@@ -140,6 +145,14 @@ V3GraphEdge::V3GraphEdge(V3Graph* graphp,
|
||||
inPushBack();
|
||||
}
|
||||
|
||||
V3GraphEdge* V3GraphEdge::relinkFromp(V3GraphVertex* newFromp) {
|
||||
V3GraphEdge *oldNxt = outNextp();
|
||||
m_outs.unlink(m_fromp->m_outs, this);
|
||||
m_fromp = newFromp;
|
||||
outPushBack();
|
||||
return oldNxt;
|
||||
}
|
||||
|
||||
void V3GraphEdge::unlinkDelete() {
|
||||
// Unlink from side
|
||||
m_outs.unlink(m_fromp->m_outs, this);
|
||||
@@ -267,6 +280,11 @@ void V3Graph::dumpDotFilePrefixed(const string& nameComment, bool colorAsSubgrap
|
||||
}
|
||||
}
|
||||
|
||||
//! Variant of dumpDotFilePrefixed without --dump option check
|
||||
void V3Graph::dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsSubgraph) {
|
||||
dumpDotFile(v3Global.debugFilename(nameComment)+".dot", colorAsSubgraph);
|
||||
}
|
||||
|
||||
void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) {
|
||||
// This generates a file used by graphviz, http://www.graphviz.org
|
||||
// "hardcoded" parameters:
|
||||
|
||||
+29
-7
@@ -119,13 +119,17 @@ public:
|
||||
/// Remove any redundant edges, weights become SUM of any other weight
|
||||
void removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp);
|
||||
|
||||
/// Call loopsVertexCb on any loops starting where specified
|
||||
/// Call loopsVertexCb on any one loop starting where specified
|
||||
void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp);
|
||||
|
||||
/// Build a subgraph of all loops starting where specified
|
||||
void subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, V3Graph* loopGraphp);
|
||||
|
||||
/// Debugging
|
||||
void dump(ostream& os=cout);
|
||||
void dumpDotFile(const string& filename, bool colorAsSubgraph);
|
||||
void dumpDotFilePrefixed(const string& nameComment, bool colorAsSubgraph=false);
|
||||
void dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsSubgraph=false);
|
||||
void userClearVertices();
|
||||
void userClearEdges();
|
||||
static void test();
|
||||
@@ -159,12 +163,18 @@ protected:
|
||||
void rank(uint32_t rank) { m_rank = rank; }
|
||||
void inUnlink() { m_ins.reset(); } // Low level; normally unlinkDelete is what you want
|
||||
void outUnlink() { m_outs.reset(); } // Low level; normally unlinkDelete is what you want
|
||||
protected:
|
||||
// CONSTRUCTORS
|
||||
V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old);
|
||||
public:
|
||||
// CONSTRUCTION
|
||||
V3GraphVertex(V3Graph* graphp);
|
||||
//! Clone copy constructor. Doesn't copy edges or user/userp.
|
||||
virtual V3GraphVertex* clone(V3Graph* graphp) const {
|
||||
return new V3GraphVertex(graphp, *this); }
|
||||
virtual ~V3GraphVertex() {}
|
||||
void unlinkEdges(V3Graph* graphp);
|
||||
void unlinkDelete(V3Graph* graphp);
|
||||
|
||||
// ACCESSORS
|
||||
virtual string name() const { return ""; }
|
||||
virtual string dotColor() const { return "black"; }
|
||||
@@ -207,6 +217,9 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp);
|
||||
|
||||
class V3GraphEdge {
|
||||
// Wires/variables aren't edges. Edges have only a single to/from vertex
|
||||
public:
|
||||
// ENUMS
|
||||
enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge
|
||||
protected:
|
||||
friend class V3Graph; friend class V3GraphVertex;
|
||||
friend class GraphAcyc; friend class GraphAcycEdge;
|
||||
@@ -222,15 +235,23 @@ protected:
|
||||
uint32_t m_user; // Marker for some algorithms
|
||||
};
|
||||
// METHODS
|
||||
void init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false);
|
||||
void cut() { m_weight = 0; } // 0 weight is same as disconnected
|
||||
void outPushBack();
|
||||
void inPushBack();
|
||||
// CONSTRUCTORS
|
||||
protected:
|
||||
V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const V3GraphEdge& old) {
|
||||
init(graphp, fromp, top, old.m_weight, old.m_cutable);
|
||||
}
|
||||
public:
|
||||
// ENUMS
|
||||
enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge
|
||||
// CONSTRUCTION
|
||||
// Add DAG from one node to the specified node
|
||||
V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false);
|
||||
//! Add DAG from one node to the specified node
|
||||
V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) {
|
||||
init(graphp, fromp, top, weight, cutable);
|
||||
}
|
||||
//! Clone copy constructor. Doesn't copy existing vertices or user/userp.
|
||||
virtual V3GraphEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new V3GraphEdge(graphp, fromp, top, *this); }
|
||||
virtual ~V3GraphEdge() {}
|
||||
// METHODS
|
||||
virtual string name() const { return m_fromp->name()+"->"+m_top->name(); }
|
||||
@@ -242,6 +263,7 @@ public:
|
||||
return top()->sortCmp(rhsp->top());
|
||||
}
|
||||
void unlinkDelete();
|
||||
V3GraphEdge* relinkFromp(V3GraphVertex* newFromp);
|
||||
// ACCESSORS
|
||||
int weight() const { return m_weight; }
|
||||
void weight(int weight) { m_weight=weight; }
|
||||
|
||||
+55
-1
@@ -376,6 +376,58 @@ void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
|
||||
GraphAlgRLoops (this, edgeFuncp, vertexp);
|
||||
}
|
||||
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - subtrees
|
||||
|
||||
class GraphAlgSubtrees : GraphAlg {
|
||||
private:
|
||||
V3Graph* m_loopGraphp;
|
||||
|
||||
//! Iterate through all connected nodes of a graph with a loop or loops.
|
||||
V3GraphVertex* vertexIterateAll(V3GraphVertex* vertexp) {
|
||||
if (V3GraphVertex* newVertexp = (V3GraphVertex*)vertexp->userp()) {
|
||||
return newVertexp;
|
||||
} else {
|
||||
newVertexp = vertexp->clone(m_loopGraphp);
|
||||
vertexp->userp(newVertexp);
|
||||
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp();
|
||||
edgep; edgep=edgep->outNextp()) {
|
||||
if (followEdge(edgep)) {
|
||||
V3GraphEdge* newEdgep = (V3GraphEdge*)edgep->userp();
|
||||
if (!newEdgep) {
|
||||
V3GraphVertex* newTop = vertexIterateAll(edgep->top());
|
||||
newEdgep = edgep->clone(m_loopGraphp, newVertexp,
|
||||
newTop);
|
||||
edgep->userp(newEdgep);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newVertexp;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
GraphAlgSubtrees(V3Graph* graphp, V3Graph* loopGraphp,
|
||||
V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp)
|
||||
: GraphAlg(graphp, edgeFuncp), m_loopGraphp (loopGraphp) {
|
||||
// Vertex::m_userp - New vertex if we have seen this vertex already
|
||||
// Edge::m_userp - New edge if we have seen this edge already
|
||||
m_graphp->userClearVertices();
|
||||
m_graphp->userClearEdges();
|
||||
(void) vertexIterateAll(vertexp);
|
||||
}
|
||||
~GraphAlgSubtrees() {}
|
||||
};
|
||||
|
||||
//! Report the entire connected graph with a loop or loops
|
||||
void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp,
|
||||
V3Graph* loopGraphp) {
|
||||
GraphAlgSubtrees (this, loopGraphp, edgeFuncp, vertexp);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - make non cutable
|
||||
@@ -465,7 +517,9 @@ void V3Graph::order() {
|
||||
}
|
||||
}
|
||||
|
||||
// Sort list of vertices by rank, then fanout
|
||||
// Sort list of vertices by rank, then fanout. Fanout is a bit of a
|
||||
// misnomer. It is the sum of all the fanouts of nodes reached from a node
|
||||
// *plus* the count of edges in to that node.
|
||||
sortVertices();
|
||||
// Sort edges by rank then fanout of node they point to
|
||||
sortEdges();
|
||||
|
||||
+19
-2
@@ -105,12 +105,16 @@ public:
|
||||
//######################################################################
|
||||
// Hashed class functions
|
||||
|
||||
void V3Hashed::hashAndInsert(AstNode* nodep) {
|
||||
V3Hashed::iterator V3Hashed::hashAndInsert(AstNode* nodep) {
|
||||
hash(nodep);
|
||||
return m_hashMmap.insert(make_pair(nodeHash(nodep), nodep));
|
||||
}
|
||||
|
||||
void V3Hashed::hash(AstNode* nodep) {
|
||||
UINFO(8," hashI "<<nodep<<endl);
|
||||
if (!nodep->user4p()) {
|
||||
HashedVisitor visitor (nodep);
|
||||
}
|
||||
m_hashMmap.insert(make_pair(nodeHash(nodep), nodep));
|
||||
}
|
||||
|
||||
bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) {
|
||||
@@ -189,3 +193,16 @@ V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) {
|
||||
return end();
|
||||
}
|
||||
|
||||
V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp) {
|
||||
UINFO(8," findD "<<nodep<<endl);
|
||||
if (!nodep->user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node");
|
||||
pair <HashMmap::iterator,HashMmap::iterator> eqrange = mmap().equal_range(nodeHash(nodep));
|
||||
for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) {
|
||||
AstNode* node2p = eqit->second;
|
||||
if (nodep != node2p && checkp->check(nodep,node2p) && sameNodes(nodep, node2p)) {
|
||||
return eqit;
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -45,6 +45,11 @@ public:
|
||||
|
||||
//============================================================================
|
||||
|
||||
struct V3HashedUserCheck {
|
||||
// Functor for V3Hashed::findDuplicate
|
||||
virtual bool check(AstNode*,AstNode*) =0;
|
||||
};
|
||||
|
||||
class V3Hashed : public VHashedBase {
|
||||
// NODE STATE
|
||||
// AstNode::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal)
|
||||
@@ -70,10 +75,12 @@ public:
|
||||
|
||||
// METHODS
|
||||
void clear() { m_hashMmap.clear(); AstNode::user4ClearTree(); }
|
||||
void hashAndInsert(AstNode* nodep); // Hash the node, and insert into map
|
||||
iterator hashAndInsert(AstNode* nodep); // Hash the node, and insert into map. Return iterator to inserted
|
||||
void hash(AstNode* nodep); // Only hash the node
|
||||
bool sameNodes(AstNode* node1p, AstNode* node2p); // After hashing, and tell if identical
|
||||
void erase(iterator it); // Remove node from structures
|
||||
iterator findDuplicate(AstNode* nodep); // Return duplicate in hash, if any
|
||||
iterator findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp); // Extra user checks for sameness
|
||||
AstNode* iteratorNodep(iterator it) { return it->second; }
|
||||
void dumpFile(const string& filename, bool tree);
|
||||
void dumpFilePrefixed(const string& nameComment, bool tree=false);
|
||||
|
||||
+6
-5
@@ -266,10 +266,11 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
|
||||
// Done. Constant.
|
||||
} else {
|
||||
// Make a new temp wire
|
||||
//if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); }
|
||||
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
|
||||
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
string newvarname = ((pinVarp->isOutput() ? "__Vcellout__" : "__Vcellinp__")
|
||||
+cellp->name()+"__"+pinp->name());
|
||||
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
|
||||
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
|
||||
+"__"+cellp->name()+"__"+pinp->name());
|
||||
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||
// Important to add statement next to cell, in case there is a generate with same named cell
|
||||
cellp->addNextHere(newvarp);
|
||||
@@ -298,8 +299,8 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
|
||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
||||
}
|
||||
if (assignp) cellp->addNextHere(assignp);
|
||||
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
|
||||
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
|
||||
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
|
||||
//if (debug()) { assignp->dumpTree(cout,"- aout:"); }
|
||||
}
|
||||
return assignp;
|
||||
}
|
||||
|
||||
+5
-3
@@ -41,6 +41,7 @@ public:
|
||||
L1364_2005,
|
||||
L1800_2005,
|
||||
L1800_2009,
|
||||
L1800_2012,
|
||||
// ***Add new elements below also***
|
||||
_ENUM_END
|
||||
};
|
||||
@@ -52,12 +53,13 @@ public:
|
||||
"1364-2001",
|
||||
"1364-2005",
|
||||
"1800-2005",
|
||||
"1800-2009"
|
||||
"1800-2009",
|
||||
"1800-2012"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
static V3LangCode mostRecent() { return V3LangCode(L1800_2009); }
|
||||
bool systemVerilog() const { return m_e == L1800_2005 || m_e == L1800_2009; }
|
||||
static V3LangCode mostRecent() { return V3LangCode(L1800_2012); }
|
||||
bool systemVerilog() const { return m_e == L1800_2005 || m_e == L1800_2009 || m_e == L1800_2012; }
|
||||
bool legal() const { return m_e != L_ERROR; }
|
||||
//
|
||||
enum en m_e;
|
||||
|
||||
@@ -136,6 +136,7 @@ private:
|
||||
// Check again
|
||||
modp = m_mods.rootp()->findIdFallback(modName)->nodep()->castNodeModule();
|
||||
if (!modp) {
|
||||
// This shouldn't throw a message as parseFile will create a AstNotFoundModule for us
|
||||
nodep->v3error("Can't resolve module reference: "<<modName);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -1114,10 +1114,14 @@ private:
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
VSymEnt* oldModSymp = m_modSymp;
|
||||
VSymEnt* oldCurSymp = m_curSymp;
|
||||
checkNoDot(nodep);
|
||||
m_ds.m_dotSymp = m_curSymp = m_statep->getScopeSym(nodep);
|
||||
m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getScopeSym(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
m_ds.m_dotSymp = m_curSymp = NULL;
|
||||
m_ds.m_dotSymp = m_curSymp = m_modSymp = NULL;
|
||||
m_modSymp = oldModSymp;
|
||||
m_curSymp = oldCurSymp;
|
||||
}
|
||||
virtual void visit(AstCellInline* nodep, AstNUser*) {
|
||||
checkNoDot(nodep);
|
||||
@@ -1320,6 +1324,7 @@ private:
|
||||
newp = new AstVarRef(nodep->fileline(), nodep->name(), false); // lvalue'ness computed later
|
||||
newp->varp(varp);
|
||||
newp->packagep(foundp->packagep());
|
||||
UINFO(9," new "<<newp<<endl);
|
||||
}
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL;
|
||||
m_ds.m_dotPos = DP_MEMBER;
|
||||
@@ -1442,6 +1447,7 @@ private:
|
||||
AstVarRef* newvscp = new AstVarRef(nodep->fileline(), vscp, nodep->lvalue());
|
||||
nodep->replaceWith(newvscp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
UINFO(9," new "<<newvscp<<endl); // Also prints taskp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -673,14 +673,15 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( !strncmp (sw, "+incdir+", 8)) {
|
||||
addIncDirUser (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
|
||||
}
|
||||
else if (parseLangExt(sw, "+systemverilogext+", V3LangCode::L1800_2009)
|
||||
else if (parseLangExt(sw, "+systemverilogext+", V3LangCode::L1800_2012)
|
||||
|| parseLangExt(sw, "+verilog1995ext+", V3LangCode::L1364_1995)
|
||||
|| parseLangExt(sw, "+verilog2001ext+", V3LangCode::L1364_2001)
|
||||
|| parseLangExt(sw, "+1364-1995ext+", V3LangCode::L1364_1995)
|
||||
|| parseLangExt(sw, "+1364-2001ext+", V3LangCode::L1364_2001)
|
||||
|| parseLangExt(sw, "+1364-2005ext+", V3LangCode::L1364_2005)
|
||||
|| parseLangExt(sw, "+1800-2005ext+", V3LangCode::L1800_2005)
|
||||
|| parseLangExt(sw, "+1800-2009ext+", V3LangCode::L1800_2009)) {
|
||||
|| parseLangExt(sw, "+1800-2009ext+", V3LangCode::L1800_2009)
|
||||
|| parseLangExt(sw, "+1800-2012ext+", V3LangCode::L1800_2012)) {
|
||||
// Nothing to do here - all done in the test
|
||||
|
||||
}
|
||||
@@ -741,6 +742,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
|
||||
else if ( onoff (sw, "-psl", flag/*ref*/) ) { m_psl = flag; }
|
||||
else if ( onoff (sw, "-public", flag/*ref*/) ) { m_public = flag; }
|
||||
else if ( onoff (sw, "-report-unoptflat", flag/*ref*/) ) { m_reportUnoptflat = flag; }
|
||||
else if ( onoff (sw, "-savable", flag/*ref*/) ) { m_savable = flag; }
|
||||
else if ( !strcmp (sw, "-sc") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = false; }
|
||||
else if ( onoff (sw, "-skip-identical", flag/*ref*/) ) { m_skipIdentical = flag; }
|
||||
@@ -765,6 +767,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
case 'a': m_oTable = flag; break;
|
||||
case 'b': m_oCombine = flag; break;
|
||||
case 'c': m_oConst = flag; break;
|
||||
case 'd': m_oDedupe = flag; break;
|
||||
case 'e': m_oCase = flag; break;
|
||||
case 'f': m_oFlopGater = flag; break;
|
||||
case 'g': m_oGate = flag; break;
|
||||
@@ -1212,6 +1215,7 @@ V3Options::V3Options() {
|
||||
m_traceDups = false;
|
||||
m_traceUnderscore = false;
|
||||
m_underlineZero = false;
|
||||
m_reportUnoptflat = false;
|
||||
m_xInitialEdge = false;
|
||||
m_xmlOnly = false;
|
||||
|
||||
@@ -1301,6 +1305,7 @@ void V3Options::optimize(int level) {
|
||||
m_oSubst = flag;
|
||||
m_oSubstConst = flag;
|
||||
m_oTable = flag;
|
||||
m_oDedupe = level >= 3;
|
||||
// And set specific optimization levels
|
||||
if (level >= 3) {
|
||||
m_inlineMult = -1; // Maximum inlining
|
||||
|
||||
@@ -89,6 +89,7 @@ class V3Options {
|
||||
bool m_traceDups; // main switch: --trace-dups
|
||||
bool m_traceUnderscore;// main switch: --trace-underscore
|
||||
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
|
||||
bool m_reportUnoptflat; // main switch: --report-unoptflat
|
||||
bool m_xInitialEdge; // main switch: --x-initial-edge
|
||||
bool m_xmlOnly; // main switch: --xml-netlist
|
||||
|
||||
@@ -131,6 +132,7 @@ class V3Options {
|
||||
bool m_oCase; // main switch: -Oe: case tree conversion
|
||||
bool m_oCombine; // main switch: -Ob: common icode packing
|
||||
bool m_oConst; // main switch: -Oc: constant folding
|
||||
bool m_oDedupe; // main switch: -Od: logic deduplication
|
||||
bool m_oExpand; // main switch: -Ox: expansion of C macros
|
||||
bool m_oFlopGater; // main switch: -Of: flop gater detection
|
||||
bool m_oGate; // main switch: -Og: gate wire elimination
|
||||
@@ -221,6 +223,7 @@ class V3Options {
|
||||
bool lintOnly() const { return m_lintOnly; }
|
||||
bool ignc() const { return m_ignc; }
|
||||
bool inhibitSim() const { return m_inhibitSim; }
|
||||
bool reportUnoptflat() const { return m_reportUnoptflat; }
|
||||
bool xInitialEdge() const { return m_xInitialEdge; }
|
||||
bool xmlOnly() const { return m_xmlOnly; }
|
||||
|
||||
@@ -266,6 +269,7 @@ class V3Options {
|
||||
bool oCase() const { return m_oCase; }
|
||||
bool oCombine() const { return m_oCombine; }
|
||||
bool oConst() const { return m_oConst; }
|
||||
bool oDedupe() const { return m_oDedupe; }
|
||||
bool oExpand() const { return m_oExpand; }
|
||||
bool oFlopGater() const { return m_oFlopGater; }
|
||||
bool oGate() const { return m_oGate; }
|
||||
|
||||
+117
-1
@@ -232,6 +232,26 @@ public:
|
||||
~OrderUser() {}
|
||||
};
|
||||
|
||||
|
||||
//######################################################################
|
||||
// Comparator classes
|
||||
|
||||
//! Comparator for width of associated variable
|
||||
struct OrderVarWidthCmp {
|
||||
bool operator() (OrderVarStdVertex* vsv1p, OrderVarStdVertex* vsv2p) {
|
||||
return vsv1p->varScp()->varp()->width()
|
||||
> vsv2p->varScp()->varp()->width();
|
||||
}
|
||||
};
|
||||
|
||||
//! Comparator for fanout of vertex
|
||||
struct OrderVarFanoutCmp {
|
||||
bool operator() (OrderVarStdVertex* vsv1p, OrderVarStdVertex* vsv2p) {
|
||||
return vsv1p->fanout() > vsv2p->fanout();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//######################################################################
|
||||
// Order class functions
|
||||
|
||||
@@ -285,6 +305,7 @@ private:
|
||||
protected:
|
||||
friend class OrderMoveDomScope;
|
||||
V3List<OrderMoveDomScope*> m_pomReadyDomScope; // List of ready domain/scope pairs, by loopId
|
||||
vector<OrderVarStdVertex*> m_unoptflatVars; // Vector of variables in UNOPTFLAT loop
|
||||
|
||||
private:
|
||||
// STATS
|
||||
@@ -418,10 +439,99 @@ private:
|
||||
if (tempWeight) edgep->weight(1); // Else the below loop detect can't see the loop
|
||||
m_graph.reportLoops(&OrderEdge::followComboConnected, vertexp); // calls OrderGraph::loopsVertexCb
|
||||
if (tempWeight) edgep->weight(0);
|
||||
if (v3Global.opt.reportUnoptflat()) {
|
||||
// Report candidate variables for splitting
|
||||
reportLoopVars(vertexp);
|
||||
// Do a subgraph for the UNOPTFLAT loop
|
||||
OrderGraph loopGraph;
|
||||
m_graph.subtreeLoops(&OrderEdge::followComboConnected,
|
||||
vertexp, &loopGraph);
|
||||
loopGraph.dumpDotFilePrefixedAlways("unoptflat");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Find all variables in an UNOPTFLAT loop
|
||||
//!
|
||||
//! Ignore vars that are 1-bit wide and don't worry about generated
|
||||
//! variables (PRE and POST vars, __Vdly__, __Vcellin__ and __VCellout).
|
||||
//! What remains are candidates for splitting to break loops.
|
||||
//!
|
||||
//! node->user3 is used to mark if we have done a particular variable.
|
||||
//! vertex->user is used to mark if we have seen this vertex before.
|
||||
//!
|
||||
//! @todo We could be cleverer in the future and consider just
|
||||
//! the width that is generated/consumed.
|
||||
void reportLoopVars(OrderVarVertex* vertexp) {
|
||||
m_graph.userClearVertices();
|
||||
AstNode::user3ClearTree();
|
||||
m_unoptflatVars.clear();
|
||||
reportLoopVarsIterate (vertexp, vertexp->color());
|
||||
AstNode::user3ClearTree();
|
||||
m_graph.userClearVertices();
|
||||
// May be very large vector, so only report the "most important"
|
||||
// elements. Up to 10 of the widest
|
||||
cerr<<V3Error::msgPrefix()
|
||||
<<" Widest candidate vars to split:"<<endl;
|
||||
sort (m_unoptflatVars.begin(), m_unoptflatVars.end(), OrderVarWidthCmp());
|
||||
int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
cerr<<V3Error::msgPrefix()<<" "
|
||||
<<varp->fileline()<<" "<<varp->prettyName()<<dec
|
||||
<<", width "<<varp->width()<<", fanout "
|
||||
<<vsvertexp->fanout()<<endl;
|
||||
}
|
||||
// Up to 10 of the most fanned out
|
||||
cerr<<V3Error::msgPrefix()
|
||||
<<" Most fanned out candidate vars to split:"<<endl;
|
||||
sort (m_unoptflatVars.begin(), m_unoptflatVars.end(),
|
||||
OrderVarFanoutCmp());
|
||||
lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
cerr<<V3Error::msgPrefix()<<" "
|
||||
<<varp->fileline()<<" "<<varp->prettyName()
|
||||
<<", width "<<dec<<varp->width()
|
||||
<<", fanout "<<vsvertexp->fanout()<<endl;
|
||||
}
|
||||
m_unoptflatVars.clear();
|
||||
}
|
||||
|
||||
void reportLoopVarsIterate(V3GraphVertex* vertexp, uint32_t color) {
|
||||
if (vertexp->user()) return; // Already done
|
||||
vertexp->user(1);
|
||||
if (OrderVarStdVertex* vsvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
|
||||
// Only reporting on standard variable vertices
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
if (!varp->user3()) {
|
||||
string name = varp->prettyName();
|
||||
if ((varp->width() != 1)
|
||||
&& (name.find("__Vdly") == string::npos)
|
||||
&& (name.find("__Vcell") == string::npos)) {
|
||||
// Variable to report on and not yet done
|
||||
m_unoptflatVars.push_back(vsvertexp);
|
||||
}
|
||||
varp->user3Inc();
|
||||
}
|
||||
}
|
||||
// Iterate through all the to and from vertices of the same color
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
if (edgep->top()->color() == color) {
|
||||
reportLoopVarsIterate(edgep->top(), color);
|
||||
}
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
if (edgep->fromp()->color() == color) {
|
||||
reportLoopVarsIterate(edgep->fromp(), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
{
|
||||
@@ -1600,7 +1710,10 @@ void OrderVisitor::process() {
|
||||
m_graph.acyclic(&V3GraphEdge::followAlwaysTrue);
|
||||
m_graph.dumpDotFilePrefixed("orderg_preasn_done", true);
|
||||
#else
|
||||
// Break cycles
|
||||
// Break cycles. Each strongly connected subgraph (including cutable
|
||||
// edges) will have its own color, and corresponds to a loop in the
|
||||
// original graph. However the new graph will be acyclic (the removed
|
||||
// edges are actually still there, just with weight 0).
|
||||
UINFO(2," Acyclic & Order...\n");
|
||||
m_graph.acyclic(&V3GraphEdge::followAlwaysTrue);
|
||||
m_graph.dumpDotFilePrefixed("orderg_acyc");
|
||||
@@ -1611,6 +1724,9 @@ void OrderVisitor::process() {
|
||||
m_graph.order();
|
||||
m_graph.dumpDotFilePrefixed("orderg_order");
|
||||
|
||||
// This finds everything that can be traced from an input (which by
|
||||
// definition are the source clocks). After this any vertex which was
|
||||
// traced has isFromInput() true.
|
||||
UINFO(2," Process Clocks...\n");
|
||||
processInputs(); // must be before processCircular
|
||||
|
||||
|
||||
+107
-41
@@ -123,6 +123,15 @@ public:
|
||||
virtual void loopsVertexCb(V3GraphVertex* vertexp);
|
||||
};
|
||||
|
||||
//! Graph for UNOPTFLAT loops
|
||||
class UnoptflatGraph : public OrderGraph {
|
||||
public:
|
||||
UnoptflatGraph() {}
|
||||
virtual ~UnoptflatGraph() {}
|
||||
// Methods
|
||||
virtual void loopsVertexCb(V3GraphVertex* vertexp);
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Vertex types
|
||||
|
||||
@@ -131,12 +140,16 @@ class OrderEitherVertex : public V3GraphVertex {
|
||||
AstSenTree* m_domainp; // Clock domain (NULL = to be computed as we iterate)
|
||||
OrderLoopId m_inLoop; // Loop number vertex is in
|
||||
bool m_isFromInput; // From input, or derrived therefrom (conservatively false)
|
||||
protected:
|
||||
OrderEitherVertex(V3Graph* graphp, const OrderEitherVertex& old)
|
||||
: V3GraphVertex(graphp, old), m_scopep(old.m_scopep), m_domainp(old.m_domainp)
|
||||
, m_inLoop(old.m_inLoop), m_isFromInput(old.m_isFromInput) {}
|
||||
public:
|
||||
OrderEitherVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp)
|
||||
: V3GraphVertex(graphp), m_scopep(scopep), m_domainp(domainp)
|
||||
, m_inLoop(LOOPID_UNKNOWN), m_isFromInput(false) {
|
||||
}
|
||||
, m_inLoop(LOOPID_UNKNOWN), m_isFromInput(false) {}
|
||||
virtual ~OrderEitherVertex() {}
|
||||
virtual OrderEitherVertex* clone(V3Graph* graphp) const = 0;
|
||||
// Methods
|
||||
virtual OrderVEdgeType type() const = 0;
|
||||
virtual bool domainMatters() = 0; // Must be in same domain when cross edge to this vertex
|
||||
@@ -152,12 +165,16 @@ public:
|
||||
};
|
||||
|
||||
class OrderInputsVertex : public OrderEitherVertex {
|
||||
OrderInputsVertex(V3Graph* graphp, const OrderInputsVertex& old)
|
||||
: OrderEitherVertex(graphp, old) {}
|
||||
public:
|
||||
OrderInputsVertex(V3Graph* graphp, AstSenTree* domainp)
|
||||
: OrderEitherVertex(graphp, NULL, domainp) {
|
||||
isFromInput(true); // By definition
|
||||
}
|
||||
virtual ~OrderInputsVertex() {}
|
||||
virtual OrderInputsVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderInputsVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_INPUTS; }
|
||||
virtual string name() const { return "*INPUTS*"; }
|
||||
virtual string dotColor() const { return "green"; }
|
||||
@@ -166,10 +183,14 @@ public:
|
||||
};
|
||||
|
||||
class OrderSettleVertex : public OrderEitherVertex {
|
||||
OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old)
|
||||
: OrderEitherVertex(graphp, old) {}
|
||||
public:
|
||||
OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp)
|
||||
: OrderEitherVertex(graphp, NULL, domainp) {}
|
||||
virtual ~OrderSettleVertex() {}
|
||||
virtual OrderSettleVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderSettleVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; }
|
||||
virtual string name() const { return "*SETTLE*"; }
|
||||
virtual string dotColor() const { return "green"; }
|
||||
@@ -180,10 +201,15 @@ public:
|
||||
class OrderLogicVertex : public OrderEitherVertex {
|
||||
AstNode* m_nodep;
|
||||
OrderMoveVertex* m_moveVxp;
|
||||
protected:
|
||||
OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old)
|
||||
: OrderEitherVertex(graphp, old), m_nodep(old.m_nodep), m_moveVxp(old.m_moveVxp) {}
|
||||
public:
|
||||
OrderLogicVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstNode* nodep)
|
||||
: OrderEitherVertex(graphp, scopep, domainp), m_nodep(nodep), m_moveVxp(NULL) {}
|
||||
virtual ~OrderLogicVertex() {}
|
||||
virtual OrderLogicVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderLogicVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOGIC; }
|
||||
virtual bool domainMatters() { return true; }
|
||||
// Accessors
|
||||
@@ -198,11 +224,14 @@ class OrderVarVertex : public OrderEitherVertex {
|
||||
AstVarScope* m_varScp;
|
||||
OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar
|
||||
bool m_isClock; // Used as clock
|
||||
protected:
|
||||
OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old)
|
||||
: OrderEitherVertex(graphp, old)
|
||||
, m_varScp(old.m_varScp), m_pilNewVertexp(old.m_pilNewVertexp), m_isClock(old.m_isClock) {}
|
||||
public:
|
||||
OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
|
||||
, m_pilNewVertexp(NULL), m_isClock(false)
|
||||
{}
|
||||
, m_pilNewVertexp(NULL), m_isClock(false) {}
|
||||
virtual ~OrderVarVertex() {}
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
|
||||
virtual OrderVEdgeType type() const = 0;
|
||||
@@ -215,66 +244,71 @@ public:
|
||||
};
|
||||
|
||||
class OrderVarStdVertex : public OrderVarVertex {
|
||||
OrderVarStdVertex(V3Graph* graphp, const OrderVarStdVertex& old)
|
||||
: OrderVarVertex(graphp, old) {}
|
||||
public:
|
||||
OrderVarStdVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderVarVertex(graphp, scopep,varScp) {}
|
||||
: OrderVarVertex(graphp, scopep, varScp) {}
|
||||
virtual ~OrderVarStdVertex() {}
|
||||
virtual OrderVarStdVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderVarStdVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSTD; }
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const {
|
||||
return new OrderVarStdVertex(graphp, scopep(), varScp());
|
||||
}
|
||||
virtual string name() const { return (cvtToStr((void*)varScp())+"\\n "+varScp()->name());}
|
||||
virtual string dotColor() const { return "skyblue"; }
|
||||
virtual bool domainMatters() { return true; }
|
||||
};
|
||||
class OrderVarPreVertex : public OrderVarVertex {
|
||||
OrderVarPreVertex(V3Graph* graphp, const OrderVarPreVertex& old)
|
||||
: OrderVarVertex(graphp, old) {}
|
||||
public:
|
||||
OrderVarPreVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderVarVertex(graphp, scopep,varScp) {}
|
||||
virtual ~OrderVarPreVertex() {}
|
||||
virtual OrderVarPreVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderVarPreVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPRE; }
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const {
|
||||
return new OrderVarPreVertex(graphp, scopep(), varScp());
|
||||
}
|
||||
virtual string name() const { return (cvtToStr((void*)varScp())+" PRE\\n "+varScp()->name());}
|
||||
virtual string dotColor() const { return "lightblue"; }
|
||||
virtual bool domainMatters() { return false; }
|
||||
};
|
||||
class OrderVarPostVertex : public OrderVarVertex {
|
||||
OrderVarPostVertex(V3Graph* graphp, const OrderVarPostVertex& old)
|
||||
: OrderVarVertex(graphp, old) {}
|
||||
public:
|
||||
OrderVarPostVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderVarVertex(graphp, scopep,varScp) {}
|
||||
virtual OrderVarPostVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderVarPostVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPOST; }
|
||||
virtual ~OrderVarPostVertex() {}
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const {
|
||||
return new OrderVarPostVertex(graphp, scopep(), varScp());
|
||||
}
|
||||
virtual string name() const { return (cvtToStr((void*)varScp())+" POST\\n "+varScp()->name());}
|
||||
virtual string dotColor() const { return "CadetBlue"; }
|
||||
virtual bool domainMatters() { return false; }
|
||||
};
|
||||
class OrderVarPordVertex : public OrderVarVertex {
|
||||
OrderVarPordVertex(V3Graph* graphp, const OrderVarPordVertex& old)
|
||||
: OrderVarVertex(graphp, old) {}
|
||||
public:
|
||||
OrderVarPordVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderVarVertex(graphp, scopep,varScp) {}
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const {
|
||||
return new OrderVarPordVertex(graphp, scopep(), varScp());
|
||||
}
|
||||
virtual ~OrderVarPordVertex() {}
|
||||
virtual OrderVarPordVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderVarPordVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPORD; }
|
||||
virtual string name() const { return (cvtToStr((void*)varScp())+" PORD\\n "+varScp()->name());}
|
||||
virtual string dotColor() const { return "NavyBlue"; }
|
||||
virtual bool domainMatters() { return false; }
|
||||
};
|
||||
class OrderVarSettleVertex : public OrderVarVertex {
|
||||
OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old)
|
||||
: OrderVarVertex(graphp, old) {}
|
||||
public:
|
||||
OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderVarVertex(graphp, scopep,varScp) {}
|
||||
virtual ~OrderVarSettleVertex() {}
|
||||
virtual OrderVarSettleVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderVarSettleVertex(graphp, *this); }
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSETTLE; }
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const {
|
||||
return new OrderVarSettleVertex(graphp, scopep(), varScp());
|
||||
}
|
||||
virtual string name() const { return (cvtToStr((void*)varScp())+" STL\\n "+varScp()->name());}
|
||||
virtual string dotColor() const { return "PowderBlue"; }
|
||||
virtual bool domainMatters() { return false; }
|
||||
@@ -288,13 +322,18 @@ class OrderLoopBeginVertex : public OrderLogicVertex {
|
||||
// However, a LoopBeginVertex is not "under" the loop per se, and it may be under another loop.
|
||||
OrderLoopId m_loopId; // Arbitrary # to ID this loop
|
||||
uint32_t m_loopColor; // Color # of loop (for debug)
|
||||
OrderLoopBeginVertex(V3Graph* graphp, const OrderLoopBeginVertex& old)
|
||||
: OrderLogicVertex(graphp, *this)
|
||||
, m_loopId(old.m_loopId), m_loopColor(old.m_loopColor) {}
|
||||
public:
|
||||
OrderLoopBeginVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstUntilStable* nodep,
|
||||
OrderLoopId loopId, uint32_t loopColor)
|
||||
: OrderLogicVertex(graphp, scopep, domainp, nodep)
|
||||
, m_loopId(loopId), m_loopColor(loopColor) {
|
||||
}
|
||||
, m_loopId(loopId), m_loopColor(loopColor) {}
|
||||
virtual ~OrderLoopBeginVertex() {}
|
||||
virtual OrderLoopBeginVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderLoopBeginVertex(graphp, *this);
|
||||
}
|
||||
// Methods
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPBEGIN; }
|
||||
virtual string name() const { return "LoopBegin_"+cvtToStr(loopId())+"_c"+cvtToStr(loopColor()); }
|
||||
@@ -306,17 +345,22 @@ public:
|
||||
};
|
||||
|
||||
class OrderLoopEndVertex : public OrderLogicVertex {
|
||||
// A end vertex points to the *same nodep* as the Begin,
|
||||
// as we need it to be a logic vertex for moving, but don't need a permanent node.
|
||||
// We won't add to the output graph though, so it shouldn't matter.
|
||||
// A end vertex points to the *same nodep* as the Begin, as we need it to
|
||||
// be a logic vertex for moving, but don't need a permanent node. We
|
||||
// won't add to the output graph though, so it shouldn't matter.
|
||||
OrderLoopBeginVertex* m_beginVertexp; // Corresponding loop begin
|
||||
OrderLoopEndVertex(V3Graph* graphp, const OrderLoopEndVertex& old)
|
||||
: OrderLogicVertex(graphp, old), m_beginVertexp(old.m_beginVertexp) {}
|
||||
public:
|
||||
OrderLoopEndVertex(V3Graph* graphp, OrderLoopBeginVertex* beginVertexp)
|
||||
: OrderLogicVertex(graphp, beginVertexp->scopep(), beginVertexp->domainp(), beginVertexp->nodep())
|
||||
: OrderLogicVertex(graphp, beginVertexp->scopep(),
|
||||
beginVertexp->domainp(), beginVertexp->nodep())
|
||||
, m_beginVertexp(beginVertexp) {
|
||||
inLoop(beginVertexp->loopId());
|
||||
}
|
||||
virtual ~OrderLoopEndVertex() {}
|
||||
virtual OrderLoopEndVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderLoopEndVertex(graphp, *this); }
|
||||
// Methods
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPEND; }
|
||||
virtual string name() const { return "LoopEnd_"+cvtToStr(inLoop())+"_c"+cvtToStr(loopColor()); }
|
||||
@@ -342,10 +386,17 @@ protected:
|
||||
// for the head of the list, see the same var name under OrderVisitor
|
||||
V3ListEnt<OrderMoveVertex*> m_pomWaitingE; // List of nodes needing inputs to become ready
|
||||
V3ListEnt<OrderMoveVertex*> m_readyVerticesE;// List of ready under domain/scope
|
||||
// CONSTRUCTORS
|
||||
OrderMoveVertex(V3Graph* graphp, const OrderMoveVertex& old)
|
||||
: V3GraphVertex(graphp, old), m_logicp(old.m_logicp), m_state(old.m_state)
|
||||
, m_domScopep(old.m_domScopep) {}
|
||||
public:
|
||||
OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp)
|
||||
: V3GraphVertex(graphp), m_logicp(logicp), m_state(POM_WAIT), m_domScopep(NULL) {}
|
||||
virtual ~OrderMoveVertex() {}
|
||||
virtual OrderMoveVertex* clone(V3Graph* graphp) const {
|
||||
return new OrderMoveVertex(graphp, *this);
|
||||
}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_MOVE; }
|
||||
virtual string dotColor() const { return logicp()->dotColor(); }
|
||||
virtual string name() const {
|
||||
@@ -376,18 +427,22 @@ public:
|
||||
// Edge types
|
||||
|
||||
class OrderEdge : public V3GraphEdge {
|
||||
protected:
|
||||
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
const OrderEdge& old)
|
||||
: V3GraphEdge(graphp, fromp, top, old) {}
|
||||
public:
|
||||
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
int weight, bool cutable=false)
|
||||
: V3GraphEdge(graphp, fromp, top, weight, cutable) {}
|
||||
virtual ~OrderEdge() {}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderEdge(graphp, fromp, top, *this);
|
||||
}
|
||||
// When ordering combo blocks with stronglyConnected, follow edges not involving pre/pos variables
|
||||
virtual bool followComboConnected() const { return true; }
|
||||
virtual bool followSequentConnected() const { return true; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderEdge(graphp, fromp, top, weight(), cutable());
|
||||
}
|
||||
static bool followComboConnected(const V3GraphEdge* edgep) {
|
||||
const OrderEdge* oedgep = dynamic_cast<const OrderEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type");
|
||||
@@ -403,14 +458,17 @@ public:
|
||||
class OrderChangeDetEdge : public OrderEdge {
|
||||
// Edge created from variable to OrderLoopEndVertex
|
||||
// Indicates a change detect will be required for this loop construct
|
||||
OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
const OrderChangeDetEdge& old)
|
||||
: OrderEdge(graphp, fromp, top, old) {}
|
||||
public:
|
||||
OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: OrderEdge(graphp, fromp, top, WEIGHT_MEDIUM, false) {}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_CHANGEDET; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderChangeDetEdge(graphp, fromp, top);
|
||||
}
|
||||
virtual ~OrderChangeDetEdge() {}
|
||||
virtual OrderChangeDetEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderChangeDetEdge(graphp, fromp, top, *this);
|
||||
}
|
||||
virtual string dotColor() const { return "blue"; }
|
||||
};
|
||||
|
||||
@@ -418,14 +476,17 @@ class OrderComboCutEdge : public OrderEdge {
|
||||
// Edge created from output of combo logic
|
||||
// Breakable if the output var is also a input,
|
||||
// in which case we'll need a change detect loop around this var.
|
||||
OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
const OrderComboCutEdge& old)
|
||||
: OrderEdge(graphp, fromp, top, old) {}
|
||||
public:
|
||||
OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_COMBOCUT; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderComboCutEdge(graphp, fromp, top);
|
||||
}
|
||||
virtual ~OrderComboCutEdge() {}
|
||||
virtual OrderComboCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderComboCutEdge(graphp, fromp, top, *this);
|
||||
}
|
||||
virtual string dotColor() const { return "yellowGreen"; }
|
||||
virtual bool followComboConnected() const { return true; }
|
||||
virtual bool followSequentConnected() const { return true; }
|
||||
@@ -435,14 +496,17 @@ class OrderPostCutEdge : public OrderEdge {
|
||||
// Edge created from output of post assignment
|
||||
// Breakable if the output var feeds back to input combo logic or another clock pin
|
||||
// in which case we'll need a change detect loop around this var.
|
||||
OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
const OrderPostCutEdge& old)
|
||||
: OrderEdge(graphp, fromp, top, old) {}
|
||||
public:
|
||||
OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_POSTCUT; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderPostCutEdge(graphp, fromp, top);
|
||||
}
|
||||
virtual ~OrderPostCutEdge() {}
|
||||
virtual OrderPostCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderPostCutEdge(graphp, fromp, top, *this);
|
||||
}
|
||||
virtual string dotColor() const { return "PaleGreen"; }
|
||||
virtual bool followComboConnected() const { return false; }
|
||||
virtual bool followSequentConnected() const { return true; }
|
||||
@@ -452,16 +516,18 @@ class OrderPreCutEdge : public OrderEdge {
|
||||
// Edge created from var_PREVAR->consuming logic vertex
|
||||
// Always breakable, just results in performance loss
|
||||
// in which case we can't optimize away the pre/post delayed assignments
|
||||
OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
|
||||
const OrderPreCutEdge& old)
|
||||
: OrderEdge(graphp, fromp, top, old) {}
|
||||
public:
|
||||
OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: OrderEdge(graphp, fromp, top, WEIGHT_PRE, CUTABLE) {}
|
||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_PRECUT; }
|
||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderPreCutEdge(graphp, fromp, top);
|
||||
virtual OrderPreCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||
return new OrderPreCutEdge(graphp, fromp, top, *this);
|
||||
}
|
||||
virtual ~OrderPreCutEdge() {}
|
||||
virtual string dotColor() const { return "khaki"; }
|
||||
virtual bool followComboConnected() const { return false; }
|
||||
virtual bool followSequentConnected() const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ struct V3ParseBisonYYSType {
|
||||
AstPackageRef* packagerefp;
|
||||
AstParseRef* parserefp;
|
||||
AstPatMember* patmemberp;
|
||||
AstPattern* patternp;
|
||||
AstPin* pinp;
|
||||
AstRange* rangep;
|
||||
AstSenTree* sentreep;
|
||||
|
||||
+41
-37
@@ -20,7 +20,7 @@
|
||||
// V3Tristate's Transformations:
|
||||
//
|
||||
// Modify the design to expand tristate logic into its
|
||||
// corresponding two state reprasentation. At the lowest levels,
|
||||
// corresponding two state representation. At the lowest levels,
|
||||
//
|
||||
// In detail:
|
||||
//
|
||||
@@ -46,12 +46,15 @@
|
||||
// logic that they may go through until they hit the module level. At
|
||||
// the module level, all the output enable signals from what can be
|
||||
// many tristate drivers are combined together to produce a single
|
||||
// driver and output enable. If the signal propigates up into higher
|
||||
// driver and output enable. If the signal propagates up into higher
|
||||
// modules, then new ports are created with for the signal with
|
||||
// suffixes __en and __out. The original port is turned from an inout
|
||||
// to an input and the __out port carries the output driver signal and
|
||||
// the __en port carried the output enable for that driver.
|
||||
//
|
||||
// Note 1800-2012 adds user defined resolution functions. This suggests
|
||||
// long term this code should be scoped-based and resolve all nodes at once
|
||||
// rather than hierarchically.
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
@@ -222,6 +225,7 @@ public:
|
||||
}
|
||||
}
|
||||
m_graph.clear();
|
||||
AstNode::user5ClearTree(); // Wipe all node user5p's that point to vertexes
|
||||
}
|
||||
void graphWalk(AstNodeModule* nodep) {
|
||||
//if (debug()>=9) m_graph.dumpDotFilePrefixed("tri_pre__"+nodep->name());
|
||||
@@ -252,7 +256,7 @@ public:
|
||||
TristateVertex* vertexp = (TristateVertex*)(nodep->user5p());
|
||||
if (!vertexp) {
|
||||
// Not v3errorSrc as no reason to stop the world
|
||||
nodep->v3error("Unsupported tristate constuct (not in propagation graph): "<<nodep->prettyTypeName());
|
||||
nodep->v3error("Unsupported tristate construct (not in propagation graph): "<<nodep->prettyTypeName());
|
||||
} else {
|
||||
// We don't warn if no vertexp->isTristate() as the creation process makes midling nodes that don't have it set
|
||||
vertexp->processed(true);
|
||||
@@ -445,7 +449,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
} else {
|
||||
if (oldpullp->direction() != pullp->direction()) {
|
||||
pullp->v3error("Unsupported: Conflicting pull directions.");
|
||||
oldpullp->v3error("... Location of conflicing pull.");
|
||||
oldpullp->v3error("... Location of conflicting pull.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,6 +498,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
|
||||
// Now go through the lhs driver map and generate the output
|
||||
// enable logic for any tristates.
|
||||
// Note there might not be any drivers.
|
||||
for (VarMap::iterator nextit, it = m_lhsmap.begin(); it != m_lhsmap.end(); it = nextit) {
|
||||
nextit = it; ++nextit;
|
||||
AstVar* invarp = (*it).first;
|
||||
@@ -518,8 +523,8 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
// if this is the top level so that we can force the final
|
||||
// tristate resolution at the top.
|
||||
AstVar* envarp = NULL;
|
||||
AstVar* outvarp = NULL;
|
||||
AstVar* lhsp = invarp;
|
||||
AstVar* outvarp = NULL; // __out
|
||||
AstVar* lhsp = invarp; // Variable to assign drive-value to (<in> or __out)
|
||||
if (!nodep->isTop() && invarp->isIO()) {
|
||||
// This var becomes an input
|
||||
invarp->varType2In(); // convert existing port to type input
|
||||
@@ -589,12 +594,10 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
undrivenp = ((!undrivenp) ? tmp
|
||||
: new AstAnd(nodep->fileline(), tmp, undrivenp));
|
||||
}
|
||||
|
||||
if (!undrivenp) { // No drivers on the bus
|
||||
V3Number ones(nodep->fileline(), lhsp->width()); ones.setAllBits1();
|
||||
undrivenp = new AstConst(nodep->fileline(), ones);
|
||||
}
|
||||
|
||||
if (!outvarp) {
|
||||
// This is the final resolution of the tristate, so we apply
|
||||
// the pull direction to any undriven pins.
|
||||
@@ -617,7 +620,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
new AstVarRef(envarp->fileline(),
|
||||
envarp, true), enp));
|
||||
}
|
||||
|
||||
// __out (child) or <in> (parent) = drive-value expression
|
||||
AstNode* assp = new AstAssignW(lhsp->fileline(),
|
||||
new AstVarRef(lhsp->fileline(),
|
||||
lhsp,
|
||||
@@ -661,7 +664,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
AstConst* enp = new AstConst(fl, numz0);
|
||||
nodep->replaceWith(newconstp);
|
||||
pushDeletep(nodep); nodep = NULL;
|
||||
newconstp->user1p(enp);
|
||||
newconstp->user1p(enp); // propagate up constant with non-Z bits as 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,7 +701,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
// two expressions with the same conditional.
|
||||
AstNode* enp = new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p);
|
||||
UINFO(9," newcond "<<enp<<endl);
|
||||
nodep->user1p(enp);
|
||||
nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable)
|
||||
expr1p->user1p(NULL);
|
||||
expr2p->user1p(NULL);
|
||||
}
|
||||
@@ -735,7 +738,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
AstNode* enp = new AstSel(nodep->fileline(), en1p,
|
||||
nodep->lsbp()->cloneTree(true), nodep->widthp()->cloneTree(true));
|
||||
UINFO(9," newsel "<<enp<<endl);
|
||||
nodep->user1p(enp);
|
||||
nodep->user1p(enp); // propagate up SEL(fromp->enable, value)
|
||||
m_tgraph.didProcess(nodep);
|
||||
}
|
||||
}
|
||||
@@ -783,7 +786,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
AstNode* en2p = getEnp(expr2p);
|
||||
AstNode* enp = new AstConcat(nodep->fileline(), en1p, en2p);
|
||||
UINFO(9," newconc "<<enp<<endl);
|
||||
nodep->user1p(enp);
|
||||
nodep->user1p(enp); // propagate up CONCAT(lhsp->enable, rhsp->enable)
|
||||
expr1p->user1p(NULL);
|
||||
expr2p->user1p(NULL);
|
||||
}
|
||||
@@ -925,14 +928,14 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
checkUnhandled(nodep);
|
||||
// Unsupported: A === 3'b000 should compare with the enables, but we don't do
|
||||
// so at present, we only compare if there is a z in the equation.
|
||||
// Otherwise we'd need to attach an enable to every signal, then optimize then
|
||||
// Otherwise we'd need to attach an enable to every signal, then optimize them
|
||||
// away later when we determine the signal has no tristate
|
||||
nodep->iterateChildren(*this);
|
||||
UINFO(9,dbgState()<<nodep<<endl);
|
||||
AstConst* constp = nodep->lhsp()->castConst(); // Constification always moves const to LHS
|
||||
AstVarRef* varrefp = nodep->rhsp()->castVarRef(); // Input variable
|
||||
if (constp && constp->user1p() && varrefp) {
|
||||
// 3'b1z0 -> ((3'b101 == __en) && (3'b100 == __in))
|
||||
// 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in))
|
||||
varrefp->unlinkFrBack();
|
||||
FileLine* fl = nodep->fileline();
|
||||
V3Number oneIfEn = constp->user1p()->castNode()->castConst()->num(); // visit(AstConst) already split into en/ones
|
||||
@@ -1021,19 +1024,20 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
// ENABLE: -> (VARREF(trisig__pinen)
|
||||
// Added complication is the signal may be an output/inout or just input with tie off (or not) up top
|
||||
// PIN PORT NEW PORTS AND CONNECTIONS
|
||||
// N/C input in(from-resolver), __out(to-resolver-only), __en(to-resolver-only)
|
||||
// N/C input in(from-resolver), __en(to-resolver-only), __out(to-resolver-only)
|
||||
// N/C inout Spec says illegal
|
||||
// N/C output Unsupported; Illegal?
|
||||
// wire input in(from-resolver-with-wire-value), __out(to-resolver-only), __en(to-resolver-only)
|
||||
// wire inout in, __out, __en
|
||||
// wire output in, __out, __en
|
||||
// const input in(from-resolver-with-const-value), __out(to-resolver-only), __en(to-resolver-only)
|
||||
// const inout Spec says illegal
|
||||
// const output Unsupported; Illegal?
|
||||
// wire input in(from-resolver-with-wire-value), __en(from-resolver-wire), __out(to-resolver-only)
|
||||
// wire inout in, __en, __out
|
||||
// wire output in, __en, __out
|
||||
// const input in(from-resolver-with-const-value), __en(from-resolver-const), __out(to-resolver-only)
|
||||
// const inout Spec says illegal
|
||||
// const output Unsupported; Illegal?
|
||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||
if (m_graphing) {
|
||||
if (nodep->user2() & U2_GRAPHING) return; // This pin is already expanded
|
||||
nodep->user2(U2_GRAPHING);
|
||||
// Find child module's new variables.
|
||||
AstVar* enModVarp = (AstVar*) nodep->modVarp()->user1p();
|
||||
if (!enModVarp) {
|
||||
if (nodep->exprp()) {
|
||||
@@ -1048,7 +1052,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
if (debug()>=9) nodep->dumpTree(cout,"-pin-pre: ");
|
||||
|
||||
// Empty/in-only; need Z to propagate
|
||||
bool inOnlyProcessing = (nodep->exprp()
|
||||
bool inDeclProcessing = (nodep->exprp()
|
||||
&& nodep->modVarp()->isInOnly()
|
||||
// Need to consider the original state instead of current state
|
||||
// as we converted tristates to inputs, which do not want to have this.
|
||||
@@ -1060,7 +1064,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
nodep->modVarp()->isOutput()));
|
||||
m_tgraph.setTristate(ucVarp);
|
||||
// We don't need a driver on the wire; the lack of one will default to tristate
|
||||
} else if (inOnlyProcessing) { // Not an input that was a converted tristate
|
||||
} else if (inDeclProcessing) { // Not an input that was a converted tristate
|
||||
// Input only may have driver in underneath module which would stomp
|
||||
// the input value. So make a temporary connection.
|
||||
AstAssignW* reAssignp = V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp, true, true);
|
||||
@@ -1077,7 +1081,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
AstVar* enVarp = new AstVar(nodep->fileline(),
|
||||
AstVarType::MODULETEMP,
|
||||
nodep->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagLogicPacked(), enModVarp->width());
|
||||
VFlagBitPacked(), enModVarp->width());
|
||||
UINFO(9," newenv "<<enVarp<<endl);
|
||||
AstPin* enpinp = new AstPin(nodep->fileline(),
|
||||
nodep->pinNum(),
|
||||
@@ -1107,9 +1111,9 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
outpinp->user2(U2_BOTH); // don't iterate the pin later
|
||||
nodep->addNextHere(outpinp);
|
||||
// Simplify
|
||||
if (inOnlyProcessing) { // Not an input that was a converted tristate
|
||||
if (inDeclProcessing) { // Not an input that was a converted tristate
|
||||
// The pin is an input, but we need an output
|
||||
// The if() above is neded because the Visitor is simple, it will flip ArraySel's and such,
|
||||
// The if() above is needed because the Visitor is simple, it will flip ArraySel's and such,
|
||||
// but if the pin is an input the earlier reconnectSimple made it a VarRef without any ArraySel, etc
|
||||
TristatePinVisitor visitor (outexprp, m_tgraph, true);
|
||||
}
|
||||
@@ -1127,29 +1131,29 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
if (debug()>=9 && inAssignp) inAssignp->dumpTree(cout,"-pin-as: ");
|
||||
|
||||
// Connect enable to output signal
|
||||
AstVarRef* outrefp;
|
||||
AstVarRef* exprrefp; // Tristate variable that the Pin's expression refers to
|
||||
if (!outAssignp) {
|
||||
outrefp = outpinp->exprp()->castVarRef();
|
||||
exprrefp = outpinp->exprp()->castVarRef();
|
||||
} else {
|
||||
outrefp = outAssignp->rhsp()->castVarRef(); // This should be the same var as the output pin
|
||||
exprrefp = outAssignp->rhsp()->castVarRef(); // This should be the same var as the output pin
|
||||
}
|
||||
if (!outrefp) { // deal with simple varref port
|
||||
if (!exprrefp) { // deal with simple varref port
|
||||
// pinReconnect should have converted this
|
||||
nodep->v3error("Unsupported tristate port expression: "<<nodep->exprp()->prettyTypeName());
|
||||
} else {
|
||||
UINFO(9,"outref "<<outrefp<<endl);
|
||||
outrefp->user1p(enrefp); // Mark as now tristated; iteration will pick it up from there
|
||||
UINFO(9,"outref "<<exprrefp<<endl);
|
||||
exprrefp->user1p(enrefp); // Mark as now tristated; iteration will pick it up from there
|
||||
if (!outAssignp) {
|
||||
mapInsertLhsVarRef(outrefp); // insertTristates will convert
|
||||
mapInsertLhsVarRef(exprrefp); // insertTristates will convert
|
||||
// // to a varref to the __out# variable
|
||||
} // else the assignment deals with the connection
|
||||
}
|
||||
|
||||
// Propagate any pullups/pulldowns upwards if necessary
|
||||
if (outrefp) {
|
||||
if (exprrefp) {
|
||||
if (AstPull* pullp = (AstPull*) nodep->modVarp()->user3p()) {
|
||||
UINFO(9, "propagate pull on "<<outrefp<<endl);
|
||||
setPullDirection(outrefp->varp(), pullp);
|
||||
UINFO(9, "propagate pull on "<<exprrefp<<endl);
|
||||
setPullDirection(exprrefp->varp(), pullp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-24
@@ -95,7 +95,9 @@ public:
|
||||
WidthVP(int width, int widthMin, Stage stage)
|
||||
: m_width(width), m_widthMin(widthMin), m_dtypep(NULL), m_stage(stage) {}
|
||||
WidthVP(AstNodeDType* dtypep, Stage stage)
|
||||
: m_width(0), m_widthMin(0), m_dtypep(dtypep), m_stage(stage) {}
|
||||
: m_width(dtypep->width()), m_widthMin(dtypep->widthMin()), m_dtypep(dtypep), m_stage(stage) {}
|
||||
WidthVP(AstNodeDType* dtypep, int width, int widthMin, Stage stage)
|
||||
: m_width(width), m_widthMin(widthMin), m_dtypep(dtypep), m_stage(stage) {}
|
||||
int width() const { return m_width; }
|
||||
int widthMin() const { return m_widthMin?m_widthMin:m_width; }
|
||||
AstNodeDType* dtypep() const { return m_dtypep; }
|
||||
@@ -118,7 +120,6 @@ private:
|
||||
AstFunc* m_funcp; // Current function
|
||||
AstInitial* m_initialp; // Current initial block
|
||||
AstAttrOf* m_attrp; // Current attribute
|
||||
AstNodeDType* m_assDTypep; // Assign LHS data type for assignment pattern
|
||||
bool m_doGenerate; // Do errors later inside generate statement
|
||||
int m_dtTables; // Number of created data type tables
|
||||
|
||||
@@ -386,7 +387,7 @@ private:
|
||||
int width = nodep->elementsConst();
|
||||
if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<<hex<<width);
|
||||
// Note width() not set on range; use elementsConst()
|
||||
if (nodep->littleEndian()) {
|
||||
if (nodep->littleEndian() && !nodep->backp()->castUnpackArrayDType()) {
|
||||
nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<<nodep->lsbConst()<<":"<<nodep->msbConst());
|
||||
}
|
||||
}
|
||||
@@ -804,6 +805,28 @@ private:
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
//if (debug()) newp->dumpTree(cout," CastOut: ");
|
||||
}
|
||||
virtual void visit(AstCastSize* nodep, AstNUser* vup) {
|
||||
if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
|
||||
//if (debug()) nodep->dumpTree(cout," CastPre: ");
|
||||
int width = nodep->rhsp()->castConst()->toSInt();
|
||||
if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; }
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType();
|
||||
if (!underDtp) {
|
||||
nodep->v3error("Unsupported: Size-changing cast on non-basic data type");
|
||||
underDtp = nodep->findLogicBoolDType()->castBasicDType();
|
||||
}
|
||||
AstNodeDType* newDtp = (underDtp->keyword().isFourstate()
|
||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||
nodep->dtypep(newDtp);
|
||||
AstNode* underp = nodep->lhsp()->unlinkFrBack();
|
||||
nodep->replaceWith(underp);
|
||||
if (underp->width()!=width) {
|
||||
fixWidthExtend(underp, newDtp);
|
||||
}
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
||||
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
||||
// Must have deterministic constant width
|
||||
@@ -970,6 +993,7 @@ private:
|
||||
virtual void visit(AstEnumItem* nodep, AstNUser* vup) {
|
||||
UINFO(5," ENUMITEM "<<nodep<<endl);
|
||||
AstNodeDType* vdtypep = vup->c()->dtypep();
|
||||
if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM");
|
||||
nodep->dtypep(vdtypep);
|
||||
if (nodep->valuep()) { // else the value will be assigned sequentially
|
||||
int width = vdtypep->width(); // Always from parent type
|
||||
@@ -1128,12 +1152,17 @@ private:
|
||||
virtual void visit(AstPattern* nodep, AstNUser* vup) {
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
UINFO(9,"PATTERN "<<nodep<<endl);
|
||||
AstNodeDType* oldAssDTypep = m_assDTypep;
|
||||
if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern }
|
||||
if (!nodep->dtypep() && vup->c()->dtypep()) { // Get it from parent assignment/pin/etc
|
||||
nodep->dtypep(vup->c()->dtypep());
|
||||
}
|
||||
AstNodeDType* vdtypep = nodep->dtypep();
|
||||
if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<<nodep->backp()->prettyTypeName());
|
||||
{
|
||||
if (!m_assDTypep) nodep->v3error("Unsupported/Illegal: Assignment pattern not underneath an assignment");
|
||||
m_assDTypep = m_assDTypep->skipRefp();
|
||||
UINFO(9," adtypep "<<m_assDTypep<<endl);
|
||||
nodep->dtypep(m_assDTypep);
|
||||
vdtypep = vdtypep->skipRefp();
|
||||
nodep->dtypep(vdtypep);
|
||||
UINFO(9," adtypep "<<vdtypep<<endl);
|
||||
nodep->dtypep(vdtypep);
|
||||
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
|
||||
// Determine replication count, and replicate initial value as widths need to be individually determined
|
||||
int times = visitPatMemberRep(patp);
|
||||
@@ -1151,7 +1180,10 @@ private:
|
||||
patp->unlinkFrBack();
|
||||
}
|
||||
}
|
||||
if (AstNodeClassDType* classp = m_assDTypep->castNodeClassDType()) {
|
||||
while (AstConstDType* classp = vdtypep->castConstDType()) {
|
||||
vdtypep = classp->subDTypep()->skipRefp();
|
||||
}
|
||||
if (AstNodeClassDType* classp = vdtypep->castNodeClassDType()) {
|
||||
// Due to "default" and tagged patterns, we need to determine
|
||||
// which member each AstPatMember corresponds to before we can
|
||||
// determine the dtypep for that PatMember's value, and then
|
||||
@@ -1205,9 +1237,9 @@ private:
|
||||
patp = it->second;
|
||||
}
|
||||
// Determine initial values
|
||||
m_assDTypep = memp;
|
||||
vdtypep = memp;
|
||||
patp->dtypep(memp);
|
||||
patp->accept(*this,WidthVP(patp->width(),patp->width(),BOTH).p());
|
||||
patp->accept(*this,WidthVP(memp,BOTH).p());
|
||||
// Convert to concat for now
|
||||
if (!newp) newp = patp->lhsp()->unlinkFrBack();
|
||||
else {
|
||||
@@ -1223,16 +1255,16 @@ private:
|
||||
else nodep->v3error("Assignment pattern with no members");
|
||||
pushDeletep(nodep); nodep = NULL; // Deletes defaultp also, if present
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: "<<m_assDTypep->prettyTypeName());
|
||||
nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: "<<vdtypep->prettyTypeName());
|
||||
}
|
||||
}
|
||||
m_assDTypep = oldAssDTypep;
|
||||
}
|
||||
virtual void visit(AstPatMember* nodep, AstNUser* vup) {
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor");
|
||||
if (!m_assDTypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath an assignment");
|
||||
AstNodeDType* vdtypep = vup->c()->dtypep();
|
||||
if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor");
|
||||
nodep->dtypep(vdtypep);
|
||||
nodep->lhsp()->dtypeFrom(nodep);
|
||||
nodep->iterateChildren(*this,WidthVP(nodep->dtypep()->width(),nodep->dtypep()->width(),BOTH).p());
|
||||
nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),BOTH).p());
|
||||
widthCheck(nodep,"LHS",nodep->lhsp(),nodep->width(),nodep->width());
|
||||
}
|
||||
int visitPatMemberRep(AstPatMember* nodep) {
|
||||
@@ -1329,14 +1361,12 @@ private:
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
//if (debug()) nodep->dumpTree(cout," AssignPre: ");
|
||||
AstNodeDType* oldAssDTypep = m_assDTypep;
|
||||
{
|
||||
//if (debug()) nodep->dumpTree(cout,"- assin: ");
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?");
|
||||
if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?");
|
||||
m_assDTypep = nodep->lhsp()->dtypep();
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(nodep->lhsp()->dtypep(),ANYSIZE,0,PRELIM).p());
|
||||
//if (debug()) nodep->dumpTree(cout,"- assign: ");
|
||||
if (!nodep->lhsp()->isDouble() && nodep->rhsp()->isDouble()) {
|
||||
spliceCvtS(nodep->rhsp(), false); // Round RHS
|
||||
@@ -1347,7 +1377,7 @@ private:
|
||||
if (awidth==0) {
|
||||
awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment
|
||||
}
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p());
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(nodep->lhsp()->dtypep(),awidth,awidth,FINAL).p());
|
||||
nodep->dtypeFrom(nodep->lhsp());
|
||||
nodep->dtypeChgWidth(awidth,awidth); // We know the assign will truncate, so rather
|
||||
// than using "width" and have the optimizer truncate the result, we do
|
||||
@@ -1356,7 +1386,6 @@ private:
|
||||
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
|
||||
//if (debug()) nodep->dumpTree(cout," AssignOut: ");
|
||||
}
|
||||
m_assDTypep = oldAssDTypep;
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||
// Excludes NodeDisplay, see below
|
||||
@@ -1681,7 +1710,7 @@ private:
|
||||
handle.relink(newp);
|
||||
pinp = newp;
|
||||
}
|
||||
pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),PRELIM).p()); pinp=NULL;
|
||||
pinp->accept(*this,WidthVP(portp->dtypep(),PRELIM).p()); pinp=NULL;
|
||||
} else if (accept_mode==1) {
|
||||
// Change data types based on above accept completion
|
||||
if (portp->isDouble()) {
|
||||
@@ -1689,7 +1718,7 @@ private:
|
||||
}
|
||||
} else if (accept_mode==2) {
|
||||
// Do PRELIM again, because above accept may have exited early due to node replacement
|
||||
pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),BOTH).p());
|
||||
pinp->accept(*this,WidthVP(portp->dtypep(),BOTH).p());
|
||||
if ((portp->isOutput() || portp->isInout())
|
||||
&& pinp->width() != portp->width()) {
|
||||
pinp->v3error("Unsupported: Function output argument '"<<portp->prettyName()<<"'"
|
||||
@@ -2585,7 +2614,6 @@ public:
|
||||
m_funcp = NULL;
|
||||
m_initialp = NULL;
|
||||
m_attrp = NULL;
|
||||
m_assDTypep = NULL;
|
||||
m_doGenerate = doGenerate;
|
||||
m_dtTables = 0;
|
||||
}
|
||||
|
||||
+30
-20
@@ -32,7 +32,7 @@
|
||||
extern void yyerror(const char*);
|
||||
extern void yyerrorf(const char* format, ...);
|
||||
|
||||
#define STATE_VERILOG_RECENT S09 // State name for most recent Verilog Version
|
||||
#define STATE_VERILOG_RECENT S12 // State name for most recent Verilog Version
|
||||
|
||||
#define PARSEP V3ParseImp::parsep()
|
||||
#define SYMP PARSEP->symp()
|
||||
@@ -135,7 +135,7 @@ void yyerrorf(const char* format, ...) {
|
||||
%a 15000
|
||||
%o 25000
|
||||
|
||||
%s V95 V01 V05 S05 S09
|
||||
%s V95 V01 V05 S05 S09 S12
|
||||
%s STRING ATTRMODE TABLE
|
||||
%s VA5 SA9 PSL VLT
|
||||
%s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR
|
||||
@@ -171,7 +171,7 @@ word [a-zA-Z0-9_]+
|
||||
|
||||
/************************************************************************/
|
||||
/* Verilog 1995 */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
{ws} { } /* otherwise ignore white-space */
|
||||
{crnl} { NEXTLINE(); } /* Count line numbers */
|
||||
/* Extensions to Verilog set, some specified by PSL */
|
||||
@@ -344,7 +344,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2001 */
|
||||
<V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
/* System Tasks */
|
||||
"$signed" { FL; return yD_SIGNED; }
|
||||
"$unsigned" { FL; return yD_UNSIGNED; }
|
||||
@@ -375,13 +375,13 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2005 */
|
||||
<V05,S05,S09,SA9,PSL>{
|
||||
<V05,S05,S09,S12,SA9,PSL>{
|
||||
/* Keywords */
|
||||
"uwire" { FL; return yWIRE; }
|
||||
}
|
||||
|
||||
/* System Verilog 2005 */
|
||||
<S05,S09,PSL>{
|
||||
<S05,S09,S12,PSL>{
|
||||
/* System Tasks */
|
||||
"$bits" { FL; return yD_BITS; }
|
||||
"$clog2" { FL; return yD_CLOG2; }
|
||||
@@ -498,7 +498,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* SystemVerilog 2005 ONLY not PSL; different rules for PSL as specified below */
|
||||
<S05,S09>{
|
||||
<S05,S09,S12>{
|
||||
/* Keywords */
|
||||
"assert" { FL; return yASSERT; }
|
||||
"const" { FL; return yCONST__LEX; }
|
||||
@@ -513,7 +513,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* SystemVerilog 2009 */
|
||||
<S09,PSL>{
|
||||
<S09,S12,PSL>{
|
||||
/* Keywords */
|
||||
"global" { FL; return yGLOBAL__LEX; }
|
||||
"unique0" { FL; return yUNIQUE0; }
|
||||
@@ -541,8 +541,17 @@ word [a-zA-Z0-9_]+
|
||||
"weak" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
}
|
||||
|
||||
/* System Verilog 2012 */
|
||||
<S12,PSL>{
|
||||
/* Keywords */
|
||||
"implements" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
|
||||
"interconnect" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
|
||||
"nettype" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
|
||||
"soft" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
|
||||
}
|
||||
|
||||
/* Default PLI rule */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
"$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng);
|
||||
yylval.strp = PARSEP->newString(AstNode::encodeName(str));
|
||||
// Lookup unencoded name including the $, to avoid hitting normal signals
|
||||
@@ -649,7 +658,7 @@ word [a-zA-Z0-9_]+
|
||||
/* PSL */
|
||||
|
||||
/*Entry into PSL; mode change */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9>{
|
||||
"psl" { yy_push_state(PSL); FL; return yPSL; }
|
||||
}
|
||||
|
||||
@@ -738,7 +747,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Meta comments */
|
||||
|
||||
/* Converted from //{cmt}verilator ...{cmt} by preprocessor */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
"/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */
|
||||
"/*verilator clock_enable*/" { FL; return yVL_CLOCK_ENABLE; }
|
||||
"/*verilator coverage_block_off*/" { FL; return yVL_COVERAGE_BLOCK_OFF; }
|
||||
@@ -773,11 +782,11 @@ word [a-zA-Z0-9_]+
|
||||
/************************************************************************/
|
||||
|
||||
/* Single character operator thingies */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9>{
|
||||
"{" { FL; return yytext[0]; }
|
||||
"}" { FL; return yytext[0]; }
|
||||
}
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
"!" { FL; return yytext[0]; }
|
||||
"#" { FL; return yytext[0]; }
|
||||
"$" { FL; return yytext[0]; }
|
||||
@@ -809,7 +818,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Operators and multi-character symbols */
|
||||
|
||||
/* Verilog 1995 Operators */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
"&&" { FL; return yP_ANDAND; }
|
||||
"||" { FL; return yP_OROR; }
|
||||
"<=" { FL; return yP_LTE; }
|
||||
@@ -831,7 +840,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2001 Operators */
|
||||
<V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
<V01,V05,VA5,S05,S09,S12,SA9,PSL>{
|
||||
"<<<" { FL; return yP_SLEFT; }
|
||||
">>>" { FL; return yP_SSRIGHT; }
|
||||
"**" { FL; return yP_POW; }
|
||||
@@ -841,7 +850,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* SystemVerilog Operators */
|
||||
<S05,S09>{
|
||||
<S05,S09,S12>{
|
||||
"'" { FL; return yP_TICK; }
|
||||
"'{" { FL; return yP_TICKBRA; }
|
||||
"==?" { FL; return yP_WILDEQUAL; }
|
||||
@@ -890,7 +899,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Identifiers and numbers */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL,VLT>{
|
||||
{escid} { FL; yylval.strp = PARSEP->newString
|
||||
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
|
||||
return yaID__LEX;
|
||||
@@ -966,7 +975,7 @@ word [a-zA-Z0-9_]+
|
||||
/************************************************************************/
|
||||
/* Attributes */
|
||||
/* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9>{
|
||||
"(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*), but (* attr_spec
|
||||
}
|
||||
|
||||
@@ -983,7 +992,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Preprocessor */
|
||||
/* Common for all SYSC header states */
|
||||
/* OPTIMIZE: we return one per line, make it one for the entire block */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
|
||||
"`accelerate" { } // Verilog-XL compatibility
|
||||
"`autoexpand_vectornets" { } // Verilog-XL compatibility
|
||||
"`celldefine" { PARSEP->inCellDefine(true); }
|
||||
@@ -1027,6 +1036,7 @@ word [a-zA-Z0-9_]+
|
||||
"`begin_keywords"[ \t]*\"VAMS[-0-9.]*\" { yy_push_state(VA5); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800-2009\" { yy_push_state(S09); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800-2012\" { yy_push_state(S12); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800+VAMS\" { yy_push_state(SA9); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
|
||||
|
||||
@@ -1058,7 +1068,7 @@ word [a-zA-Z0-9_]+
|
||||
/************************************************************************/
|
||||
/* Default rules - leave last */
|
||||
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
|
||||
<V95,V01,V05,VA5,S05,S09,S12,SA9,PSL,VLT>{
|
||||
"`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); }
|
||||
"//"[^\n]* { } /* throw away single line comments */
|
||||
. { FL; return yytext[0]; } /* return single char ops. */
|
||||
|
||||
+5
-3
@@ -651,7 +651,7 @@ description: // ==IEEE: description
|
||||
| program_declaration { }
|
||||
| package_declaration { }
|
||||
| package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
|
||||
//UNSUP bind_directive { }
|
||||
| bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
|
||||
// unsupported // IEEE: config_declaration
|
||||
// // Verilator only
|
||||
| vltItem { }
|
||||
@@ -2184,6 +2184,7 @@ statementVerilatorPragmas<nodep>:
|
||||
|
||||
foperator_assignment<nodep>: // IEEE: operator_assignment (for first part of expression)
|
||||
fexprLvalue '=' delayE expr { $$ = new AstAssign($2,$1,$4); }
|
||||
| fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = NULL; $3->v3error("Unsupported: $fopen with multichannel descriptor. Add ,\"w\" as second argument to open a file descriptor."); }
|
||||
| fexprLvalue '=' yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen($3,$1,$5,$7); }
|
||||
//
|
||||
//UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { UNSUP }
|
||||
@@ -2313,7 +2314,7 @@ patternKey<nodep>: // IEEE: merge structure_pattern_key, array_pattern_key, ass
|
||||
| yaID__ETC { $$ = new AstText($<fl>1,*$1); }
|
||||
;
|
||||
|
||||
assignment_pattern<nodep>: // ==IEEE: assignment_pattern
|
||||
assignment_pattern<patternp>: // ==IEEE: assignment_pattern
|
||||
// This doesn't match the text of the spec. I think a : is missing, or example code needed
|
||||
// yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
|
||||
// // "'{ const_expression }" is same as patternList with one entry
|
||||
@@ -2824,6 +2825,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
|
||||
// // Spec only allows primary with addition of a type reference
|
||||
// // We'll be more general, and later assert LHS was a type.
|
||||
//UNSUP ~l~expr yP_TICK '(' expr ')' { UNSUP }
|
||||
| yaINTNUM yP_TICK '(' expr ')' { $$ = new AstCastSize($2,$4,new AstConst($1->fileline(),*$1)); }
|
||||
//
|
||||
// // IEEE: assignment_pattern_expression
|
||||
// // IEEE: streaming_concatenation
|
||||
@@ -2875,7 +2877,7 @@ exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
|
||||
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
|
||||
// // We allow more here than the spec requires
|
||||
//UNSUP ~l~exprScope assignment_pattern { UNSUP }
|
||||
//UNSUP data_type assignment_pattern { UNSUP }
|
||||
| data_type assignment_pattern { $$ = $2; $2->childDTypep($1); }
|
||||
| assignment_pattern { $$ = $1; }
|
||||
//
|
||||
//UNSUP streaming_concatenation { UNSUP }
|
||||
|
||||
@@ -365,6 +365,7 @@ sub new {
|
||||
'v3' => 0,
|
||||
verilator_flags => ["-cc",
|
||||
"-Mdir $self->{obj_dir}",
|
||||
"-OD", # As currently disabled unless -O3
|
||||
"--debug-check"],
|
||||
verilator_flags2 => [],
|
||||
verilator_make_gcc => 1,
|
||||
|
||||
@@ -14,9 +14,9 @@ use Cwd qw(chdir);
|
||||
|
||||
my @args = @ARGV;
|
||||
chdir("$FindBin::Bin/..");
|
||||
$ENV{PWD} = Cwd::getcwd(); # Else chdir leaves the .. which confuses later commands
|
||||
|
||||
@args = map { s!.*test_regress/!!; $_; } @args;
|
||||
|
||||
print "cd $ENV{PWD} && $FindBin::Bin/bootstrap.pl ",join(' ',@args),"\n";
|
||||
exec("./driver.pl", @args);
|
||||
die;
|
||||
|
||||
+25
-5
@@ -3,7 +3,14 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2012 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
bit a_finished;
|
||||
bit b_finished;
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
wire [31:0] o;
|
||||
wire si = 1'b0;
|
||||
|
||||
@@ -18,6 +25,13 @@ module t;
|
||||
// Inputs
|
||||
.si (si));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (!a_finished) $stop;
|
||||
if (!b_finished) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module InstModule (
|
||||
@@ -28,10 +42,7 @@ module InstModule (
|
||||
endmodule
|
||||
|
||||
program Prog (input si);
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
initial a_finished = 1'b1;
|
||||
endprogram
|
||||
|
||||
module ExampInst (o,i);
|
||||
@@ -55,3 +66,12 @@ module ExampInst (o,i);
|
||||
|
||||
endmodule
|
||||
|
||||
// Check bind at top level
|
||||
bind InstModule Prog2 instProg2
|
||||
(/*AUTOBIND*/
|
||||
.si (si));
|
||||
|
||||
// Check program declared after bind
|
||||
program Prog2 (input si);
|
||||
initial b_finished = 1'b1;
|
||||
endprogram
|
||||
|
||||
@@ -10,11 +10,14 @@ module t;
|
||||
|
||||
mc_t o;
|
||||
|
||||
logic [15:0] allones = 16'hffff;
|
||||
|
||||
initial begin
|
||||
if (4'shf > 4'sh0) $stop;
|
||||
if (signed'(4'hf) > 4'sh0) $stop;
|
||||
if (4'hf < 4'h0) $stop;
|
||||
if (unsigned'(4'shf) < 4'h0) $stop;
|
||||
if (4'(allones) !== 4'hf) $stop;
|
||||
|
||||
o = tocast_t'(4'b1);
|
||||
if (o != 4'b1) $stop;
|
||||
|
||||
@@ -17,7 +17,6 @@ compile (
|
||||
%Warning-CDCRSTLOGIC: See details in obj_dir/t_cdc_async_bad/Vt_cdc_async_bad__cdc.txt
|
||||
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6a_bad_n
|
||||
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6b_bad_n
|
||||
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst3_bad_n
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
@@ -21,9 +21,8 @@ double sc_time_stamp () {
|
||||
VM_PREFIX* topp = NULL;
|
||||
|
||||
void clockit(int clk1, int clk0) {
|
||||
#ifdef T_CLK_2IN_VEC
|
||||
topp->clks = clk1<<1 | clk0;
|
||||
#else
|
||||
#ifndef T_CLK_2IN_VEC
|
||||
topp->c1 = clk1;
|
||||
topp->c0 = clk0;
|
||||
#endif
|
||||
@@ -38,6 +37,7 @@ int main (int argc, char *argv[]) {
|
||||
topp = new VM_PREFIX;
|
||||
topp->check = 0;
|
||||
clockit(0,0);
|
||||
main_time+=10;
|
||||
|
||||
Verilated::debug(0);
|
||||
|
||||
@@ -49,6 +49,9 @@ int main (int argc, char *argv[]) {
|
||||
clockit(1, 1);
|
||||
clockit(1, 0);
|
||||
clockit(0, 0);
|
||||
clockit(0, 1);
|
||||
clockit(1, 0);
|
||||
clockit(0, 0);
|
||||
}
|
||||
topp->check = 1;
|
||||
clockit(0,0);
|
||||
|
||||
@@ -7,18 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["$Self->{t_dir}/$Self->{name}.cpp"],
|
||||
verilator_flags2 => ["--exe"],
|
||||
);
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"],
|
||||
vcs_flags2 => ['-assert'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
+111
-19
@@ -3,19 +3,75 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2010 by Wilson Snyder.
|
||||
|
||||
module t (
|
||||
`ifdef T_CLK_2IN_VEC
|
||||
input [1:0] clks,
|
||||
`ifndef VERILATOR
|
||||
module t;
|
||||
/*AUTOREGINPUT*/
|
||||
// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
|
||||
reg c0; // To t2 of t2.v
|
||||
reg c1; // To t2 of t2.v
|
||||
reg check; // To t2 of t2.v
|
||||
reg [1:0] clks; // To t2 of t2.v
|
||||
// End of automatics
|
||||
t2 t2 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clks (clks[1:0]),
|
||||
.c0 (c0),
|
||||
.c1 (c1),
|
||||
.check (check));
|
||||
task clockit (input v1, v0);
|
||||
c1 = v1;
|
||||
c0 = v0;
|
||||
clks[1] = v1;
|
||||
clks[0] = v0;
|
||||
`ifdef TEST_VERBOSE $write("[%0t] c1=%x c0=%x\n", $time,v0,v1); `endif
|
||||
#1;
|
||||
endtask
|
||||
initial begin
|
||||
check = '0;
|
||||
c0 = '0;
|
||||
c1 = '0;
|
||||
clks = '0;
|
||||
#1
|
||||
t2.clear();
|
||||
#10;
|
||||
for (int i=0; i<2; i++) begin
|
||||
clockit(0, 0);
|
||||
clockit(0, 0);
|
||||
clockit(0, 1);
|
||||
clockit(1, 1);
|
||||
clockit(0, 0);
|
||||
clockit(1, 1);
|
||||
clockit(1, 0);
|
||||
clockit(0, 0);
|
||||
clockit(1, 0);
|
||||
clockit(0, 1);
|
||||
clockit(0, 0);
|
||||
end
|
||||
check = 1;
|
||||
clockit(0, 0);
|
||||
end
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
`ifdef VERILATOR
|
||||
`define t2 t
|
||||
`else
|
||||
`define t2 t2
|
||||
`endif
|
||||
|
||||
module `t2 (
|
||||
input [1:0] clks,
|
||||
input c0,
|
||||
input c1,
|
||||
`endif
|
||||
input check
|
||||
);
|
||||
|
||||
`ifdef T_CLK_2IN_VEC
|
||||
wire c0 = clks[0];
|
||||
wire c1 = clks[1];
|
||||
wire clk0 = clks[0];
|
||||
wire clk1 = clks[1];
|
||||
`else
|
||||
wire clk0 = c0;
|
||||
wire clk1 = c1;
|
||||
`endif
|
||||
|
||||
integer p0 = 0;
|
||||
@@ -24,46 +80,82 @@ module t (
|
||||
integer n0 = 0;
|
||||
integer n1 = 0;
|
||||
integer n01 = 0;
|
||||
integer vp = 0;
|
||||
integer vn = 0;
|
||||
integer vpn = 0;
|
||||
task clear;
|
||||
`ifdef TEST_VERBOSE $display("[%0t] clear\n",$time); `endif
|
||||
p0 = 0;
|
||||
p1 = 0;
|
||||
p01 = 0;
|
||||
n0 = 0;
|
||||
n1 = 0;
|
||||
n01 = 0;
|
||||
vp = 0;
|
||||
vn = 0;
|
||||
vpn = 0;
|
||||
endtask
|
||||
|
||||
`define display_counts(text) begin \
|
||||
$write("[%0t] ",$time); \
|
||||
`ifdef T_CLK_2IN_VEC $write(" 2v "); `endif \
|
||||
$write(text); \
|
||||
$write(": %0d %0d %0d %0d %0d %0d\n", p0, p1, p01, n0, n1, n01); \
|
||||
$write(": %0d %0d %0d %0d %0d %0d %0d %0d %0d\n", p0, p1, p01, n0, n1, n01, vp, vn, vpn); \
|
||||
end
|
||||
|
||||
always @ (posedge c0) begin
|
||||
always @ (posedge clk0) begin
|
||||
p0 = p0 + 1; // Want blocking, so don't miss clock counts
|
||||
`ifdef TEST_VERBOSE `display_counts("posedge 0"); `endif
|
||||
end
|
||||
always @ (posedge c1) begin
|
||||
always @ (posedge clk1) begin
|
||||
p1 = p1 + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("posedge 1"); `endif
|
||||
end
|
||||
always @ (posedge c0 or posedge c1) begin
|
||||
always @ (posedge clk0 or posedge clk1) begin
|
||||
p01 = p01 + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("posedge *"); `endif
|
||||
end
|
||||
always @ (negedge c0) begin
|
||||
|
||||
always @ (negedge clk0) begin
|
||||
n0 = n0 + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("negedge 0"); `endif
|
||||
end
|
||||
always @ (negedge c1) begin
|
||||
always @ (negedge clk1) begin
|
||||
n1 = n1 + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("negedge 1"); `endif
|
||||
end
|
||||
always @ (negedge c0 or negedge c1) begin
|
||||
always @ (negedge clk0 or negedge clk1) begin
|
||||
n01 = n01 + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("negedge *"); `endif
|
||||
end
|
||||
|
||||
`ifndef VERILATOR
|
||||
always @ (posedge clks) begin
|
||||
vp = vp + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("pos vec"); `endif
|
||||
end
|
||||
always @ (negedge clks) begin
|
||||
vn = vn + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("neg vec"); `endif
|
||||
end
|
||||
always @ (posedge clks or negedge clks) begin
|
||||
vpn = vpn + 1;
|
||||
`ifdef TEST_VERBOSE `display_counts("or vec"); `endif
|
||||
end
|
||||
`endif
|
||||
|
||||
always @ (posedge check) begin
|
||||
if (p0!=4) $stop;
|
||||
if (p1!=4) $stop;
|
||||
if (p01!=6) $stop;
|
||||
if (n0!=4) $stop;
|
||||
if (n1!=4) $stop;
|
||||
if (n01!=6) $stop;
|
||||
if (p0!=6) $stop;
|
||||
if (p1!=6) $stop;
|
||||
if (p01!=10) $stop;
|
||||
if (n0!=6) $stop;
|
||||
if (n1!=6) $stop;
|
||||
if (n01!=10) $stop;
|
||||
`ifndef VERILATOR
|
||||
if (vp!=6) $stop;
|
||||
if (vn!=6) $stop;
|
||||
if (vpn!=12) $stop;
|
||||
`endif
|
||||
$write("*-* All Finished *-*\n");
|
||||
end
|
||||
|
||||
|
||||
@@ -9,13 +9,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
|
||||
top_filename("t/t_clk_2in.v");
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["+define+T_CLK_2IN_VEC=1 $Self->{t_dir}/t_clk_2in.cpp"],
|
||||
verilator_flags2 => ["--exe"],
|
||||
v_flags2 => ["+define+T_CLK_2IN_VEC=1"],
|
||||
verilator_flags2 => ["--exe $Self->{t_dir}/t_clk_2in.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--stats"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt}) {
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,61 @@
|
||||
// DESCRIPTION: Verilator: Dedupe optimization test.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// Contributed 2012 by Varun Koyyalagunta, Centaur Technology.
|
||||
|
||||
module t(res,d,clk,en);
|
||||
output res;
|
||||
input d,en,clk;
|
||||
wire q0,q1,q2,q3;
|
||||
|
||||
flop_gated_latch f0(q0,d,clk,en);
|
||||
flop_gated_latch f1(q1,d,clk,en);
|
||||
flop_gated_flop f2(q2,d,clk,en);
|
||||
flop_gated_flop f3(q3,d,clk,en);
|
||||
assign res = (q0 + q1) * (q2 - q3);
|
||||
endmodule
|
||||
|
||||
module flop_gated_latch(q,d,clk,en);
|
||||
input d, clk, en;
|
||||
output q;
|
||||
wire gated_clock;
|
||||
clock_gate_latch clock_gate(gated_clock, clk, en);
|
||||
always @(posedge gated_clock) begin
|
||||
q <= d;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module flop_gated_flop(q,d,clk,en);
|
||||
input d, clk, en;
|
||||
output q;
|
||||
wire gated_clock;
|
||||
clock_gate_flop clock_gate(gated_clock, clk, en);
|
||||
always @(posedge gated_clock) begin
|
||||
q <= d;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module clock_gate_latch (gated_clk, clk, clken);
|
||||
output gated_clk;
|
||||
input clk, clken;
|
||||
reg clken_latched /*verilator clock_enable*/;
|
||||
assign gated_clk = clk & clken_latched ;
|
||||
|
||||
wire clkb = ~clk;
|
||||
always @(clkb or clken)
|
||||
if(clkb) clken_latched = clken;
|
||||
|
||||
endmodule
|
||||
|
||||
module clock_gate_flop (gated_clk, clk, clken);
|
||||
output gated_clk;
|
||||
input clk, clken;
|
||||
reg clken_r /*verilator clock_enable*/;
|
||||
assign gated_clk = clk & clken_r ;
|
||||
|
||||
always @(negedge clk)
|
||||
clken_r <= clken;
|
||||
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--stats"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt}) {
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 6);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,123 @@
|
||||
// DESCRIPTION: Verilator: Dedupe optimization test.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
|
||||
// Contributed 2012 by Varun Koyyalagunta, Centaur Technology.
|
||||
//
|
||||
// Test consists of the follow logic tree, which has many obvious
|
||||
// places for dedupe:
|
||||
/*
|
||||
output
|
||||
+
|
||||
--------------/ \--------------
|
||||
/ \
|
||||
+ +
|
||||
----/ \----- ----/ \----
|
||||
/ + / +
|
||||
+ / \ + / \
|
||||
-/ \- a b -/ \- a b
|
||||
/ \ / \
|
||||
+ + + +
|
||||
/ \ / \ / \ / \
|
||||
a b c d a b c d
|
||||
*/
|
||||
|
||||
module t(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
wire left,right;
|
||||
add add(sum,left,right,clk);
|
||||
l l(left,a,b,c,d,clk);
|
||||
r r(right,a,b,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module l(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
wire left, right;
|
||||
add add(sum,left,right,clk);
|
||||
ll ll(left,a,b,c,d,clk);
|
||||
lr lr(right,a,b,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module ll(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
wire left, right;
|
||||
add add(sum,left,right,clk);
|
||||
lll lll(left,a,b,c,d,clk);
|
||||
llr llr(right,a,b,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module lll(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add add(sum,a,b,clk);
|
||||
endmodule
|
||||
|
||||
module llr(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add add(sum,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module lr(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add add(sum,a,b,clk);
|
||||
endmodule
|
||||
|
||||
module r(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
wire left, right;
|
||||
add add(sum,left,right,clk);
|
||||
rl rl(left,a,b,c,d,clk);
|
||||
rr rr(right,a,b,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module rr(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add add(sum,a,b,clk);
|
||||
endmodule
|
||||
|
||||
module rl(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
wire left, right;
|
||||
add add(sum,left,right,clk);
|
||||
rll rll(left,a,b,c,d,clk);
|
||||
rlr rlr(right,a,b,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module rll(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add2 add(sum,a,b,clk);
|
||||
endmodule
|
||||
|
||||
module rlr(sum,a,b,c,d,clk);
|
||||
output sum;
|
||||
input a,b,c,d,clk;
|
||||
add2 add(sum,c,d,clk);
|
||||
endmodule
|
||||
|
||||
module add(sum,x,y,clk);
|
||||
output sum;
|
||||
input x,y,clk;
|
||||
reg t1,t2;
|
||||
always @(posedge clk) begin
|
||||
sum <= x + y;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module add2(sum,x,y,clk);
|
||||
output sum;
|
||||
input x,y,clk;
|
||||
reg t1,t2;
|
||||
always @(posedge clk) begin
|
||||
sum <= x + y;
|
||||
end
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["-Wno-UNOPTFLAT"]
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,41 @@
|
||||
// DESCRIPTION: Verilator: Simple test of unoptflat
|
||||
//
|
||||
// Trigger the DETECTARRAY error.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jeremy Bennett.
|
||||
|
||||
localparam ID_MSB = 1;
|
||||
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
typedef struct packed {
|
||||
logic [ID_MSB:0] id;
|
||||
} context_t;
|
||||
|
||||
context_t tsb;
|
||||
|
||||
assign tsb.id = {tsb.id[0], clk};
|
||||
|
||||
initial begin
|
||||
tsb.id = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge clk) begin
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("tsb.id = %x\n", tsb.id);
|
||||
`endif
|
||||
|
||||
if (tsb.id[1] != 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["-Wno-UNOPTFLAT"]
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,43 @@
|
||||
// DESCRIPTION: Verilator: Simple test of unoptflat
|
||||
//
|
||||
// This should trigger the DETECTARRAY error like t_detectarray_1.v, but in
|
||||
// fact it casuses a broken link error. The only difference is that the struct
|
||||
// is defined using a constant rather than a localparam.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jeremy Bennett.
|
||||
|
||||
localparam ID_MSB = 1;
|
||||
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
typedef struct packed {
|
||||
logic [1:0] id;
|
||||
} context_t;
|
||||
|
||||
context_t tsb;
|
||||
|
||||
assign tsb.id = {tsb.id[0], clk};
|
||||
|
||||
initial begin
|
||||
tsb.id = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge clk) begin
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("tsb.id = %x\n", tsb.id);
|
||||
`endif
|
||||
|
||||
if (tsb.id[1] != 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -54,9 +54,12 @@ sub printfll {
|
||||
my %names;
|
||||
foreach my $line (split /\n/, $grep) {
|
||||
next if $line !~ /%[a-z0-9]*ll/;
|
||||
next if $line !~ /\blong\S+long\b/; # Assume a cast
|
||||
print "$line\n";
|
||||
if ($line =~ /^([^:]+)/) {
|
||||
$names{$1} = 1;
|
||||
print "$line\n";
|
||||
} else {
|
||||
$names{UNKNOWN} = 1;
|
||||
}
|
||||
}
|
||||
if (keys %names) {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
`ifdef INLINE_A //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
|
||||
bmod bsub3 (.clk, .n(3));
|
||||
bmod bsub2 (.clk, .n(2));
|
||||
bmod bsub1 (.clk, .n(1));
|
||||
bmod bsub0 (.clk, .n(0));
|
||||
endmodule
|
||||
|
||||
module bmod
|
||||
(input clk,
|
||||
input [31:0] n);
|
||||
|
||||
`ifdef INLINE_B //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
|
||||
cmod csub (.clk, .n);
|
||||
|
||||
endmodule
|
||||
|
||||
module cmod
|
||||
(input clk, input [31:0] n);
|
||||
|
||||
`ifdef INLINE_C //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
|
||||
reg [31:0] clocal;
|
||||
always @ (posedge clk) clocal <= n;
|
||||
|
||||
dmod dsub (.clk, .n);
|
||||
endmodule
|
||||
|
||||
module dmod (input clk, input [31:0] n);
|
||||
|
||||
`ifdef INLINE_D //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
|
||||
reg [31:0] dlocal;
|
||||
always @ (posedge clk) dlocal <= n;
|
||||
|
||||
int cyc;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc+1;
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
if (cyc>10) begin
|
||||
`ifdef TEST_VERBOSE $display("%m: csub.clocal=%0d dlocal=%0d", csub.clocal, dlocal); `endif
|
||||
if (csub.clocal !== n) $stop;
|
||||
if (dlocal !== n) $stop;
|
||||
end
|
||||
if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_A'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_A +define+INLINE_B'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_A +define+INLINE_C'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_A +define+INLINE_D'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_B'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_B +define+INLINE_C'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_B +define+INLINE_D'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_C'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_C +define+INLINE_D'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_inst_dtree.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+INLINE_D'],
|
||||
verilator_flags2 => ['-trace'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -22,7 +22,7 @@ module t (/*AUTOARG*/
|
||||
counter c1 (.clkm(clk),
|
||||
.c_data(c1_data),
|
||||
.i_value(4'h1));
|
||||
counter c2 (.clkm(clk),
|
||||
counter2 c2 (.clkm(clk),
|
||||
.c_data(c2_data),
|
||||
.i_value(4'h2));
|
||||
|
||||
@@ -66,3 +66,16 @@ module counter
|
||||
c_data.value <= c_data.value + 1;
|
||||
end
|
||||
endmodule : counter
|
||||
|
||||
module counter2(clkm, c_data, i_value);
|
||||
input clkm;
|
||||
counter_io c_data;
|
||||
input logic [3:0] i_value;
|
||||
|
||||
always @ (posedge clkm) begin
|
||||
if (c_data.reset)
|
||||
c_data.value <= i_value;
|
||||
else
|
||||
c_data.value <= c_data.value + 1;
|
||||
end
|
||||
endmodule : counter2
|
||||
|
||||
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug102");
|
||||
|
||||
compile (
|
||||
v_flags => ["--lint-only"]
|
||||
verilator_flags2 => ["--lint-only"]
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
||||
@@ -10,13 +10,12 @@ interface counter_io;
|
||||
modport core_side (output reset, input value);
|
||||
endinterface
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk,
|
||||
module t
|
||||
(// Inputs
|
||||
input clk,
|
||||
counter_io.counter_side c_data
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc=1;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -40,6 +40,10 @@ module m1;
|
||||
localparam PAR1DUP = PAR1+2; // Check we propagate parameters properly
|
||||
parameter PAR1 = 0;
|
||||
m2 #(PAR1MINUS1) m2 ();
|
||||
|
||||
// Packed arrays
|
||||
localparam [1:0][3:0] PACKED_PARAM = { 4'h3, 4'h6 };
|
||||
initial if (PACKED_PARAM != 8'h36) $stop;
|
||||
endmodule
|
||||
|
||||
module m2;
|
||||
|
||||
@@ -9,12 +9,13 @@ module t (/*AUTOARG*/
|
||||
);
|
||||
input clk;
|
||||
|
||||
s1 s1 ();
|
||||
s2 s2 ();
|
||||
s3 s3 ();
|
||||
s4 s4 ();
|
||||
s5 s5 ();
|
||||
s6 s6 ();
|
||||
v95 v95 ();
|
||||
v01 v01 ();
|
||||
v05 v05 ();
|
||||
s05 s05 ();
|
||||
s09 s09 ();
|
||||
a23 a23 ();
|
||||
s12 s12 ();
|
||||
|
||||
initial begin
|
||||
$finish;
|
||||
@@ -22,31 +23,37 @@ module t (/*AUTOARG*/
|
||||
endmodule
|
||||
|
||||
`begin_keywords "1364-1995"
|
||||
module s1;
|
||||
module v95;
|
||||
integer signed; initial signed = 1;
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "1364-2001"
|
||||
module s2;
|
||||
module v01;
|
||||
integer bit; initial bit = 1;
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "1364-2005"
|
||||
module s3;
|
||||
module v05;
|
||||
integer final; initial final = 1;
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "1800-2005"
|
||||
module s4;
|
||||
module s05;
|
||||
integer global; initial global = 1;
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "1800-2009"
|
||||
module s5;
|
||||
module s09;
|
||||
integer soft; initial soft = 1;
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "1800-2012"
|
||||
module s12;
|
||||
final begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end
|
||||
@@ -54,7 +61,7 @@ endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "VAMS-2.3"
|
||||
module s6;
|
||||
module a23;
|
||||
real foo; initial foo = sqrt(2.0);
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,28 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2009 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
// No endian warning here
|
||||
wire [7:0] pack [3:0];
|
||||
|
||||
initial begin
|
||||
pack[0] = 8'h78;
|
||||
pack[1] = 8'h88;
|
||||
pack[2] = 8'h98;
|
||||
pack[3] = 8'hA8;
|
||||
if (pack[0] !== 8'h78) $stop;
|
||||
if (pack[1] !== 8'h88) $stop;
|
||||
if (pack[2] !== 8'h98) $stop;
|
||||
if (pack[3] !== 8'hA8) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -39,6 +39,14 @@ module t;
|
||||
// bit vec2d[2][3];
|
||||
} pack3_t;
|
||||
|
||||
const b4_t b4_const_a = '{1'b1, 1'b0, 1'b0, 1'b1};
|
||||
|
||||
// Cast to a pattern - note bits are tagged out of order
|
||||
const b4_t b4_const_b = b4_t'{ b1 : 1'b0, b0 : 1'b1, b3 : 1'b1, b2 : 1'b0 };
|
||||
|
||||
wire b4_t b4_wire;
|
||||
assign b4_wire = '{1'b1, 1'b0, 1'b1, 1'b0};
|
||||
|
||||
pack2_t arr[2];
|
||||
|
||||
initial begin
|
||||
@@ -94,8 +102,19 @@ module t;
|
||||
if (q != 4'b1011) $stop;
|
||||
end
|
||||
|
||||
if (b4_const_a != 4'b1001) $stop;
|
||||
if (b4_const_b != 4'b1001) $stop;
|
||||
if (b4_wire != 4'b1010) $stop;
|
||||
if (pat(4'b1100, 4'b1100)) $stop;
|
||||
if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
function pat(b4_t in, logic [3:0] cmp);
|
||||
if (in !== cmp) $stop;
|
||||
pat = 1'b0;
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#if defined(T_TRACE_CAT)
|
||||
# include "Vt_trace_cat.h"
|
||||
#elif defined(T_TRACE_CAT_REOPEN)
|
||||
# include "Vt_trace_cat_reopen.h"
|
||||
#elif defined(T_TRACE_CAT_RENEW)
|
||||
# include "Vt_trace_cat_renew.h"
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() {
|
||||
return (double)main_time;
|
||||
}
|
||||
|
||||
const char* trace_name() {
|
||||
static char name[1000];
|
||||
#if defined(T_TRACE_CAT)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat/simpart_%04d.vcd", (int)main_time);
|
||||
#elif defined(T_TRACE_CAT_REOPEN)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat_reopen/simpart_%04d.vcd", (int)main_time);
|
||||
#elif defined(T_TRACE_CAT_RENEW)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat_renew/simpart_%04d.vcd", (int)main_time);
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
return name;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
VM_PREFIX* top = new VM_PREFIX("top");
|
||||
|
||||
Verilated::debug(0);
|
||||
Verilated::traceEverOn(true);
|
||||
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp,99);
|
||||
|
||||
tfp->open(trace_name());
|
||||
|
||||
top->clk = 0;
|
||||
|
||||
while (main_time < 190) { // Creates 2 files
|
||||
top->clk = ~top->clk;
|
||||
top->eval();
|
||||
|
||||
if ((main_time % 100) == 0) {
|
||||
#if defined(T_TRACE_CAT)
|
||||
tfp->openNext(true);
|
||||
#elif defined(T_TRACE_CAT_REOPEN)
|
||||
tfp->close();
|
||||
tfp->open(trace_name());
|
||||
#elif defined(T_TRACE_CAT_RENEW)
|
||||
tfp->close();
|
||||
delete tfp;
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp,99);
|
||||
tfp->open(trace_name());
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
}
|
||||
tfp->dump((unsigned int)(main_time));
|
||||
++main_time;
|
||||
}
|
||||
tfp->close();
|
||||
top->final();
|
||||
printf ("*-* All Finished *-*\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:39:34 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000001 #
|
||||
1$
|
||||
#1
|
||||
0$
|
||||
#2
|
||||
b00000000000000000000000000000010 #
|
||||
1$
|
||||
#3
|
||||
0$
|
||||
#4
|
||||
b00000000000000000000000000000011 #
|
||||
1$
|
||||
#5
|
||||
0$
|
||||
#6
|
||||
b00000000000000000000000000000100 #
|
||||
1$
|
||||
#7
|
||||
0$
|
||||
#8
|
||||
b00000000000000000000000000000101 #
|
||||
1$
|
||||
#9
|
||||
0$
|
||||
#10
|
||||
b00000000000000000000000000000110 #
|
||||
1$
|
||||
#11
|
||||
0$
|
||||
#12
|
||||
b00000000000000000000000000000111 #
|
||||
1$
|
||||
#13
|
||||
0$
|
||||
#14
|
||||
b00000000000000000000000000001000 #
|
||||
1$
|
||||
#15
|
||||
0$
|
||||
#16
|
||||
b00000000000000000000000000001001 #
|
||||
1$
|
||||
#17
|
||||
0$
|
||||
#18
|
||||
b00000000000000000000000000001010 #
|
||||
1$
|
||||
#19
|
||||
0$
|
||||
#20
|
||||
b00000000000000000000000000001011 #
|
||||
1$
|
||||
#21
|
||||
0$
|
||||
#22
|
||||
b00000000000000000000000000001100 #
|
||||
1$
|
||||
#23
|
||||
0$
|
||||
#24
|
||||
b00000000000000000000000000001101 #
|
||||
1$
|
||||
#25
|
||||
0$
|
||||
#26
|
||||
b00000000000000000000000000001110 #
|
||||
1$
|
||||
#27
|
||||
0$
|
||||
#28
|
||||
b00000000000000000000000000001111 #
|
||||
1$
|
||||
#29
|
||||
0$
|
||||
#30
|
||||
b00000000000000000000000000010000 #
|
||||
1$
|
||||
#31
|
||||
0$
|
||||
#32
|
||||
b00000000000000000000000000010001 #
|
||||
1$
|
||||
#33
|
||||
0$
|
||||
#34
|
||||
b00000000000000000000000000010010 #
|
||||
1$
|
||||
#35
|
||||
0$
|
||||
#36
|
||||
b00000000000000000000000000010011 #
|
||||
1$
|
||||
#37
|
||||
0$
|
||||
#38
|
||||
b00000000000000000000000000010100 #
|
||||
1$
|
||||
#39
|
||||
0$
|
||||
#40
|
||||
b00000000000000000000000000010101 #
|
||||
1$
|
||||
#41
|
||||
0$
|
||||
#42
|
||||
b00000000000000000000000000010110 #
|
||||
1$
|
||||
#43
|
||||
0$
|
||||
#44
|
||||
b00000000000000000000000000010111 #
|
||||
1$
|
||||
#45
|
||||
0$
|
||||
#46
|
||||
b00000000000000000000000000011000 #
|
||||
1$
|
||||
#47
|
||||
0$
|
||||
#48
|
||||
b00000000000000000000000000011001 #
|
||||
1$
|
||||
#49
|
||||
0$
|
||||
#50
|
||||
b00000000000000000000000000011010 #
|
||||
1$
|
||||
#51
|
||||
0$
|
||||
#52
|
||||
b00000000000000000000000000011011 #
|
||||
1$
|
||||
#53
|
||||
0$
|
||||
#54
|
||||
b00000000000000000000000000011100 #
|
||||
1$
|
||||
#55
|
||||
0$
|
||||
#56
|
||||
b00000000000000000000000000011101 #
|
||||
1$
|
||||
#57
|
||||
0$
|
||||
#58
|
||||
b00000000000000000000000000011110 #
|
||||
1$
|
||||
#59
|
||||
0$
|
||||
#60
|
||||
b00000000000000000000000000011111 #
|
||||
1$
|
||||
#61
|
||||
0$
|
||||
#62
|
||||
b00000000000000000000000000100000 #
|
||||
1$
|
||||
#63
|
||||
0$
|
||||
#64
|
||||
b00000000000000000000000000100001 #
|
||||
1$
|
||||
#65
|
||||
0$
|
||||
#66
|
||||
b00000000000000000000000000100010 #
|
||||
1$
|
||||
#67
|
||||
0$
|
||||
#68
|
||||
b00000000000000000000000000100011 #
|
||||
1$
|
||||
#69
|
||||
0$
|
||||
#70
|
||||
b00000000000000000000000000100100 #
|
||||
1$
|
||||
#71
|
||||
0$
|
||||
#72
|
||||
b00000000000000000000000000100101 #
|
||||
1$
|
||||
#73
|
||||
0$
|
||||
#74
|
||||
b00000000000000000000000000100110 #
|
||||
1$
|
||||
#75
|
||||
0$
|
||||
#76
|
||||
b00000000000000000000000000100111 #
|
||||
1$
|
||||
#77
|
||||
0$
|
||||
#78
|
||||
b00000000000000000000000000101000 #
|
||||
1$
|
||||
#79
|
||||
0$
|
||||
#80
|
||||
b00000000000000000000000000101001 #
|
||||
1$
|
||||
#81
|
||||
0$
|
||||
#82
|
||||
b00000000000000000000000000101010 #
|
||||
1$
|
||||
#83
|
||||
0$
|
||||
#84
|
||||
b00000000000000000000000000101011 #
|
||||
1$
|
||||
#85
|
||||
0$
|
||||
#86
|
||||
b00000000000000000000000000101100 #
|
||||
1$
|
||||
#87
|
||||
0$
|
||||
#88
|
||||
b00000000000000000000000000101101 #
|
||||
1$
|
||||
#89
|
||||
0$
|
||||
#90
|
||||
b00000000000000000000000000101110 #
|
||||
1$
|
||||
#91
|
||||
0$
|
||||
#92
|
||||
b00000000000000000000000000101111 #
|
||||
1$
|
||||
#93
|
||||
0$
|
||||
#94
|
||||
b00000000000000000000000000110000 #
|
||||
1$
|
||||
#95
|
||||
0$
|
||||
#96
|
||||
b00000000000000000000000000110001 #
|
||||
1$
|
||||
#97
|
||||
0$
|
||||
#98
|
||||
b00000000000000000000000000110010 #
|
||||
1$
|
||||
#99
|
||||
0$
|
||||
#100
|
||||
b00000000000000000000000000110011 #
|
||||
1$
|
||||
#101
|
||||
0$
|
||||
#102
|
||||
b00000000000000000000000000110100 #
|
||||
1$
|
||||
#103
|
||||
0$
|
||||
#104
|
||||
b00000000000000000000000000110101 #
|
||||
1$
|
||||
#105
|
||||
0$
|
||||
#106
|
||||
b00000000000000000000000000110110 #
|
||||
1$
|
||||
#107
|
||||
0$
|
||||
#108
|
||||
b00000000000000000000000000110111 #
|
||||
1$
|
||||
#109
|
||||
0$
|
||||
#110
|
||||
b00000000000000000000000000111000 #
|
||||
1$
|
||||
#111
|
||||
0$
|
||||
#112
|
||||
b00000000000000000000000000111001 #
|
||||
1$
|
||||
#113
|
||||
0$
|
||||
#114
|
||||
b00000000000000000000000000111010 #
|
||||
1$
|
||||
#115
|
||||
0$
|
||||
#116
|
||||
b00000000000000000000000000111011 #
|
||||
1$
|
||||
#117
|
||||
0$
|
||||
#118
|
||||
b00000000000000000000000000111100 #
|
||||
1$
|
||||
#119
|
||||
0$
|
||||
#120
|
||||
b00000000000000000000000000111101 #
|
||||
1$
|
||||
#121
|
||||
0$
|
||||
#122
|
||||
b00000000000000000000000000111110 #
|
||||
1$
|
||||
#123
|
||||
0$
|
||||
#124
|
||||
b00000000000000000000000000111111 #
|
||||
1$
|
||||
#125
|
||||
0$
|
||||
#126
|
||||
b00000000000000000000000001000000 #
|
||||
1$
|
||||
#127
|
||||
0$
|
||||
#128
|
||||
b00000000000000000000000001000001 #
|
||||
1$
|
||||
#129
|
||||
0$
|
||||
#130
|
||||
b00000000000000000000000001000010 #
|
||||
1$
|
||||
#131
|
||||
0$
|
||||
#132
|
||||
b00000000000000000000000001000011 #
|
||||
1$
|
||||
#133
|
||||
0$
|
||||
#134
|
||||
b00000000000000000000000001000100 #
|
||||
1$
|
||||
#135
|
||||
0$
|
||||
#136
|
||||
b00000000000000000000000001000101 #
|
||||
1$
|
||||
#137
|
||||
0$
|
||||
#138
|
||||
b00000000000000000000000001000110 #
|
||||
1$
|
||||
#139
|
||||
0$
|
||||
#140
|
||||
b00000000000000000000000001000111 #
|
||||
1$
|
||||
#141
|
||||
0$
|
||||
#142
|
||||
b00000000000000000000000001001000 #
|
||||
1$
|
||||
#143
|
||||
0$
|
||||
#144
|
||||
b00000000000000000000000001001001 #
|
||||
1$
|
||||
#145
|
||||
0$
|
||||
#146
|
||||
b00000000000000000000000001001010 #
|
||||
1$
|
||||
#147
|
||||
0$
|
||||
#148
|
||||
b00000000000000000000000001001011 #
|
||||
1$
|
||||
#149
|
||||
0$
|
||||
#150
|
||||
b00000000000000000000000001001100 #
|
||||
1$
|
||||
#151
|
||||
0$
|
||||
#152
|
||||
b00000000000000000000000001001101 #
|
||||
1$
|
||||
#153
|
||||
0$
|
||||
#154
|
||||
b00000000000000000000000001001110 #
|
||||
1$
|
||||
#155
|
||||
0$
|
||||
#156
|
||||
b00000000000000000000000001001111 #
|
||||
1$
|
||||
#157
|
||||
0$
|
||||
#158
|
||||
b00000000000000000000000001010000 #
|
||||
1$
|
||||
#159
|
||||
0$
|
||||
#160
|
||||
b00000000000000000000000001010001 #
|
||||
1$
|
||||
#161
|
||||
0$
|
||||
#162
|
||||
b00000000000000000000000001010010 #
|
||||
1$
|
||||
#163
|
||||
0$
|
||||
#164
|
||||
b00000000000000000000000001010011 #
|
||||
1$
|
||||
#165
|
||||
0$
|
||||
#166
|
||||
b00000000000000000000000001010100 #
|
||||
1$
|
||||
#167
|
||||
0$
|
||||
#168
|
||||
b00000000000000000000000001010101 #
|
||||
1$
|
||||
#169
|
||||
0$
|
||||
#170
|
||||
b00000000000000000000000001010110 #
|
||||
1$
|
||||
#171
|
||||
0$
|
||||
#172
|
||||
b00000000000000000000000001010111 #
|
||||
1$
|
||||
#173
|
||||
0$
|
||||
#174
|
||||
b00000000000000000000000001011000 #
|
||||
1$
|
||||
#175
|
||||
0$
|
||||
#176
|
||||
b00000000000000000000000001011001 #
|
||||
1$
|
||||
#177
|
||||
0$
|
||||
#178
|
||||
b00000000000000000000000001011010 #
|
||||
1$
|
||||
#179
|
||||
0$
|
||||
#180
|
||||
b00000000000000000000000001011011 #
|
||||
1$
|
||||
#181
|
||||
0$
|
||||
#182
|
||||
b00000000000000000000000001011100 #
|
||||
1$
|
||||
#183
|
||||
0$
|
||||
#184
|
||||
b00000000000000000000000001011101 #
|
||||
1$
|
||||
#185
|
||||
0$
|
||||
#186
|
||||
b00000000000000000000000001011110 #
|
||||
1$
|
||||
#187
|
||||
0$
|
||||
#188
|
||||
b00000000000000000000000001011111 #
|
||||
1$
|
||||
#189
|
||||
0$
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
system("cat $Self->{obj_dir}/simpart*.vcd > $Self->{obj_dir}/simall.vcd");
|
||||
|
||||
vcd_identical ("$Self->{obj_dir}/simall.vcd",
|
||||
"t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,16 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Wilson Snyder.
|
||||
|
||||
module t
|
||||
(
|
||||
input wire clk
|
||||
);
|
||||
|
||||
integer cyc; initial cyc = 0;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,765 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:18:07 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000001 #
|
||||
1$
|
||||
#1
|
||||
0$
|
||||
#2
|
||||
b00000000000000000000000000000010 #
|
||||
1$
|
||||
#3
|
||||
0$
|
||||
#4
|
||||
b00000000000000000000000000000011 #
|
||||
1$
|
||||
#5
|
||||
0$
|
||||
#6
|
||||
b00000000000000000000000000000100 #
|
||||
1$
|
||||
#7
|
||||
0$
|
||||
#8
|
||||
b00000000000000000000000000000101 #
|
||||
1$
|
||||
#9
|
||||
0$
|
||||
#10
|
||||
b00000000000000000000000000000110 #
|
||||
1$
|
||||
#11
|
||||
0$
|
||||
#12
|
||||
b00000000000000000000000000000111 #
|
||||
1$
|
||||
#13
|
||||
0$
|
||||
#14
|
||||
b00000000000000000000000000001000 #
|
||||
1$
|
||||
#15
|
||||
0$
|
||||
#16
|
||||
b00000000000000000000000000001001 #
|
||||
1$
|
||||
#17
|
||||
0$
|
||||
#18
|
||||
b00000000000000000000000000001010 #
|
||||
1$
|
||||
#19
|
||||
0$
|
||||
#20
|
||||
b00000000000000000000000000001011 #
|
||||
1$
|
||||
#21
|
||||
0$
|
||||
#22
|
||||
b00000000000000000000000000001100 #
|
||||
1$
|
||||
#23
|
||||
0$
|
||||
#24
|
||||
b00000000000000000000000000001101 #
|
||||
1$
|
||||
#25
|
||||
0$
|
||||
#26
|
||||
b00000000000000000000000000001110 #
|
||||
1$
|
||||
#27
|
||||
0$
|
||||
#28
|
||||
b00000000000000000000000000001111 #
|
||||
1$
|
||||
#29
|
||||
0$
|
||||
#30
|
||||
b00000000000000000000000000010000 #
|
||||
1$
|
||||
#31
|
||||
0$
|
||||
#32
|
||||
b00000000000000000000000000010001 #
|
||||
1$
|
||||
#33
|
||||
0$
|
||||
#34
|
||||
b00000000000000000000000000010010 #
|
||||
1$
|
||||
#35
|
||||
0$
|
||||
#36
|
||||
b00000000000000000000000000010011 #
|
||||
1$
|
||||
#37
|
||||
0$
|
||||
#38
|
||||
b00000000000000000000000000010100 #
|
||||
1$
|
||||
#39
|
||||
0$
|
||||
#40
|
||||
b00000000000000000000000000010101 #
|
||||
1$
|
||||
#41
|
||||
0$
|
||||
#42
|
||||
b00000000000000000000000000010110 #
|
||||
1$
|
||||
#43
|
||||
0$
|
||||
#44
|
||||
b00000000000000000000000000010111 #
|
||||
1$
|
||||
#45
|
||||
0$
|
||||
#46
|
||||
b00000000000000000000000000011000 #
|
||||
1$
|
||||
#47
|
||||
0$
|
||||
#48
|
||||
b00000000000000000000000000011001 #
|
||||
1$
|
||||
#49
|
||||
0$
|
||||
#50
|
||||
b00000000000000000000000000011010 #
|
||||
1$
|
||||
#51
|
||||
0$
|
||||
#52
|
||||
b00000000000000000000000000011011 #
|
||||
1$
|
||||
#53
|
||||
0$
|
||||
#54
|
||||
b00000000000000000000000000011100 #
|
||||
1$
|
||||
#55
|
||||
0$
|
||||
#56
|
||||
b00000000000000000000000000011101 #
|
||||
1$
|
||||
#57
|
||||
0$
|
||||
#58
|
||||
b00000000000000000000000000011110 #
|
||||
1$
|
||||
#59
|
||||
0$
|
||||
#60
|
||||
b00000000000000000000000000011111 #
|
||||
1$
|
||||
#61
|
||||
0$
|
||||
#62
|
||||
b00000000000000000000000000100000 #
|
||||
1$
|
||||
#63
|
||||
0$
|
||||
#64
|
||||
b00000000000000000000000000100001 #
|
||||
1$
|
||||
#65
|
||||
0$
|
||||
#66
|
||||
b00000000000000000000000000100010 #
|
||||
1$
|
||||
#67
|
||||
0$
|
||||
#68
|
||||
b00000000000000000000000000100011 #
|
||||
1$
|
||||
#69
|
||||
0$
|
||||
#70
|
||||
b00000000000000000000000000100100 #
|
||||
1$
|
||||
#71
|
||||
0$
|
||||
#72
|
||||
b00000000000000000000000000100101 #
|
||||
1$
|
||||
#73
|
||||
0$
|
||||
#74
|
||||
b00000000000000000000000000100110 #
|
||||
1$
|
||||
#75
|
||||
0$
|
||||
#76
|
||||
b00000000000000000000000000100111 #
|
||||
1$
|
||||
#77
|
||||
0$
|
||||
#78
|
||||
b00000000000000000000000000101000 #
|
||||
1$
|
||||
#79
|
||||
0$
|
||||
#80
|
||||
b00000000000000000000000000101001 #
|
||||
1$
|
||||
#81
|
||||
0$
|
||||
#82
|
||||
b00000000000000000000000000101010 #
|
||||
1$
|
||||
#83
|
||||
0$
|
||||
#84
|
||||
b00000000000000000000000000101011 #
|
||||
1$
|
||||
#85
|
||||
0$
|
||||
#86
|
||||
b00000000000000000000000000101100 #
|
||||
1$
|
||||
#87
|
||||
0$
|
||||
#88
|
||||
b00000000000000000000000000101101 #
|
||||
1$
|
||||
#89
|
||||
0$
|
||||
#90
|
||||
b00000000000000000000000000101110 #
|
||||
1$
|
||||
#91
|
||||
0$
|
||||
#92
|
||||
b00000000000000000000000000101111 #
|
||||
1$
|
||||
#93
|
||||
0$
|
||||
#94
|
||||
b00000000000000000000000000110000 #
|
||||
1$
|
||||
#95
|
||||
0$
|
||||
#96
|
||||
b00000000000000000000000000110001 #
|
||||
1$
|
||||
#97
|
||||
0$
|
||||
#98
|
||||
b00000000000000000000000000110010 #
|
||||
1$
|
||||
#99
|
||||
0$
|
||||
#100
|
||||
b00000000000000000000000000110011 #
|
||||
1$
|
||||
#101
|
||||
0$
|
||||
#102
|
||||
b00000000000000000000000000110100 #
|
||||
1$
|
||||
#103
|
||||
0$
|
||||
#104
|
||||
b00000000000000000000000000110101 #
|
||||
1$
|
||||
#105
|
||||
0$
|
||||
#106
|
||||
b00000000000000000000000000110110 #
|
||||
1$
|
||||
#107
|
||||
0$
|
||||
#108
|
||||
b00000000000000000000000000110111 #
|
||||
1$
|
||||
#109
|
||||
0$
|
||||
#110
|
||||
b00000000000000000000000000111000 #
|
||||
1$
|
||||
#111
|
||||
0$
|
||||
#112
|
||||
b00000000000000000000000000111001 #
|
||||
1$
|
||||
#113
|
||||
0$
|
||||
#114
|
||||
b00000000000000000000000000111010 #
|
||||
1$
|
||||
#115
|
||||
0$
|
||||
#116
|
||||
b00000000000000000000000000111011 #
|
||||
1$
|
||||
#117
|
||||
0$
|
||||
#118
|
||||
b00000000000000000000000000111100 #
|
||||
1$
|
||||
#119
|
||||
0$
|
||||
#120
|
||||
b00000000000000000000000000111101 #
|
||||
1$
|
||||
#121
|
||||
0$
|
||||
#122
|
||||
b00000000000000000000000000111110 #
|
||||
1$
|
||||
#123
|
||||
0$
|
||||
#124
|
||||
b00000000000000000000000000111111 #
|
||||
1$
|
||||
#125
|
||||
0$
|
||||
#126
|
||||
b00000000000000000000000001000000 #
|
||||
1$
|
||||
#127
|
||||
0$
|
||||
#128
|
||||
b00000000000000000000000001000001 #
|
||||
1$
|
||||
#129
|
||||
0$
|
||||
#130
|
||||
b00000000000000000000000001000010 #
|
||||
1$
|
||||
#131
|
||||
0$
|
||||
#132
|
||||
b00000000000000000000000001000011 #
|
||||
1$
|
||||
#133
|
||||
0$
|
||||
#134
|
||||
b00000000000000000000000001000100 #
|
||||
1$
|
||||
#135
|
||||
0$
|
||||
#136
|
||||
b00000000000000000000000001000101 #
|
||||
1$
|
||||
#137
|
||||
0$
|
||||
#138
|
||||
b00000000000000000000000001000110 #
|
||||
1$
|
||||
#139
|
||||
0$
|
||||
#140
|
||||
b00000000000000000000000001000111 #
|
||||
1$
|
||||
#141
|
||||
0$
|
||||
#142
|
||||
b00000000000000000000000001001000 #
|
||||
1$
|
||||
#143
|
||||
0$
|
||||
#144
|
||||
b00000000000000000000000001001001 #
|
||||
1$
|
||||
#145
|
||||
0$
|
||||
#146
|
||||
b00000000000000000000000001001010 #
|
||||
1$
|
||||
#147
|
||||
0$
|
||||
#148
|
||||
b00000000000000000000000001001011 #
|
||||
1$
|
||||
#149
|
||||
0$
|
||||
#150
|
||||
b00000000000000000000000001001100 #
|
||||
1$
|
||||
#151
|
||||
0$
|
||||
#152
|
||||
b00000000000000000000000001001101 #
|
||||
1$
|
||||
#153
|
||||
0$
|
||||
#154
|
||||
b00000000000000000000000001001110 #
|
||||
1$
|
||||
#155
|
||||
0$
|
||||
#156
|
||||
b00000000000000000000000001001111 #
|
||||
1$
|
||||
#157
|
||||
0$
|
||||
#158
|
||||
b00000000000000000000000001010000 #
|
||||
1$
|
||||
#159
|
||||
0$
|
||||
#160
|
||||
b00000000000000000000000001010001 #
|
||||
1$
|
||||
#161
|
||||
0$
|
||||
#162
|
||||
b00000000000000000000000001010010 #
|
||||
1$
|
||||
#163
|
||||
0$
|
||||
#164
|
||||
b00000000000000000000000001010011 #
|
||||
1$
|
||||
#165
|
||||
0$
|
||||
#166
|
||||
b00000000000000000000000001010100 #
|
||||
1$
|
||||
#167
|
||||
0$
|
||||
#168
|
||||
b00000000000000000000000001010101 #
|
||||
1$
|
||||
#169
|
||||
0$
|
||||
#170
|
||||
b00000000000000000000000001010110 #
|
||||
1$
|
||||
#171
|
||||
0$
|
||||
#172
|
||||
b00000000000000000000000001010111 #
|
||||
1$
|
||||
#173
|
||||
0$
|
||||
#174
|
||||
b00000000000000000000000001011000 #
|
||||
1$
|
||||
#175
|
||||
0$
|
||||
#176
|
||||
b00000000000000000000000001011001 #
|
||||
1$
|
||||
#177
|
||||
0$
|
||||
#178
|
||||
b00000000000000000000000001011010 #
|
||||
1$
|
||||
#179
|
||||
0$
|
||||
#180
|
||||
b00000000000000000000000001011011 #
|
||||
1$
|
||||
#181
|
||||
0$
|
||||
#182
|
||||
b00000000000000000000000001011100 #
|
||||
1$
|
||||
#183
|
||||
0$
|
||||
#184
|
||||
b00000000000000000000000001011101 #
|
||||
1$
|
||||
#185
|
||||
0$
|
||||
#186
|
||||
b00000000000000000000000001011110 #
|
||||
1$
|
||||
#187
|
||||
0$
|
||||
#188
|
||||
b00000000000000000000000001011111 #
|
||||
1$
|
||||
#189
|
||||
0$
|
||||
#190
|
||||
b00000000000000000000000001100000 #
|
||||
1$
|
||||
#191
|
||||
0$
|
||||
#192
|
||||
b00000000000000000000000001100001 #
|
||||
1$
|
||||
#193
|
||||
0$
|
||||
#194
|
||||
b00000000000000000000000001100010 #
|
||||
1$
|
||||
#195
|
||||
0$
|
||||
#196
|
||||
b00000000000000000000000001100011 #
|
||||
1$
|
||||
#197
|
||||
0$
|
||||
#198
|
||||
b00000000000000000000000001100100 #
|
||||
1$
|
||||
#199
|
||||
0$
|
||||
#200
|
||||
b00000000000000000000000001100101 #
|
||||
1$
|
||||
#201
|
||||
0$
|
||||
#202
|
||||
b00000000000000000000000001100110 #
|
||||
1$
|
||||
#203
|
||||
0$
|
||||
#204
|
||||
b00000000000000000000000001100111 #
|
||||
1$
|
||||
#205
|
||||
0$
|
||||
#206
|
||||
b00000000000000000000000001101000 #
|
||||
1$
|
||||
#207
|
||||
0$
|
||||
#208
|
||||
b00000000000000000000000001101001 #
|
||||
1$
|
||||
#209
|
||||
0$
|
||||
#210
|
||||
b00000000000000000000000001101010 #
|
||||
1$
|
||||
#211
|
||||
0$
|
||||
#212
|
||||
b00000000000000000000000001101011 #
|
||||
1$
|
||||
#213
|
||||
0$
|
||||
#214
|
||||
b00000000000000000000000001101100 #
|
||||
1$
|
||||
#215
|
||||
0$
|
||||
#216
|
||||
b00000000000000000000000001101101 #
|
||||
1$
|
||||
#217
|
||||
0$
|
||||
#218
|
||||
b00000000000000000000000001101110 #
|
||||
1$
|
||||
#219
|
||||
0$
|
||||
#220
|
||||
b00000000000000000000000001101111 #
|
||||
1$
|
||||
#221
|
||||
0$
|
||||
#222
|
||||
b00000000000000000000000001110000 #
|
||||
1$
|
||||
#223
|
||||
0$
|
||||
#224
|
||||
b00000000000000000000000001110001 #
|
||||
1$
|
||||
#225
|
||||
0$
|
||||
#226
|
||||
b00000000000000000000000001110010 #
|
||||
1$
|
||||
#227
|
||||
0$
|
||||
#228
|
||||
b00000000000000000000000001110011 #
|
||||
1$
|
||||
#229
|
||||
0$
|
||||
#230
|
||||
b00000000000000000000000001110100 #
|
||||
1$
|
||||
#231
|
||||
0$
|
||||
#232
|
||||
b00000000000000000000000001110101 #
|
||||
1$
|
||||
#233
|
||||
0$
|
||||
#234
|
||||
b00000000000000000000000001110110 #
|
||||
1$
|
||||
#235
|
||||
0$
|
||||
#236
|
||||
b00000000000000000000000001110111 #
|
||||
1$
|
||||
#237
|
||||
0$
|
||||
#238
|
||||
b00000000000000000000000001111000 #
|
||||
1$
|
||||
#239
|
||||
0$
|
||||
#240
|
||||
b00000000000000000000000001111001 #
|
||||
1$
|
||||
#241
|
||||
0$
|
||||
#242
|
||||
b00000000000000000000000001111010 #
|
||||
1$
|
||||
#243
|
||||
0$
|
||||
#244
|
||||
b00000000000000000000000001111011 #
|
||||
1$
|
||||
#245
|
||||
0$
|
||||
#246
|
||||
b00000000000000000000000001111100 #
|
||||
1$
|
||||
#247
|
||||
0$
|
||||
#248
|
||||
b00000000000000000000000001111101 #
|
||||
1$
|
||||
#249
|
||||
0$
|
||||
#250
|
||||
b00000000000000000000000001111110 #
|
||||
1$
|
||||
#251
|
||||
0$
|
||||
#252
|
||||
b00000000000000000000000001111111 #
|
||||
1$
|
||||
#253
|
||||
0$
|
||||
#254
|
||||
b00000000000000000000000010000000 #
|
||||
1$
|
||||
#255
|
||||
0$
|
||||
#256
|
||||
b00000000000000000000000010000001 #
|
||||
1$
|
||||
#257
|
||||
0$
|
||||
#258
|
||||
b00000000000000000000000010000010 #
|
||||
1$
|
||||
#259
|
||||
0$
|
||||
#260
|
||||
b00000000000000000000000010000011 #
|
||||
1$
|
||||
#261
|
||||
0$
|
||||
#262
|
||||
b00000000000000000000000010000100 #
|
||||
1$
|
||||
#263
|
||||
0$
|
||||
#264
|
||||
b00000000000000000000000010000101 #
|
||||
1$
|
||||
#265
|
||||
0$
|
||||
#266
|
||||
b00000000000000000000000010000110 #
|
||||
1$
|
||||
#267
|
||||
0$
|
||||
#268
|
||||
b00000000000000000000000010000111 #
|
||||
1$
|
||||
#269
|
||||
0$
|
||||
#270
|
||||
b00000000000000000000000010001000 #
|
||||
1$
|
||||
#271
|
||||
0$
|
||||
#272
|
||||
b00000000000000000000000010001001 #
|
||||
1$
|
||||
#273
|
||||
0$
|
||||
#274
|
||||
b00000000000000000000000010001010 #
|
||||
1$
|
||||
#275
|
||||
0$
|
||||
#276
|
||||
b00000000000000000000000010001011 #
|
||||
1$
|
||||
#277
|
||||
0$
|
||||
#278
|
||||
b00000000000000000000000010001100 #
|
||||
1$
|
||||
#279
|
||||
0$
|
||||
#280
|
||||
b00000000000000000000000010001101 #
|
||||
1$
|
||||
#281
|
||||
0$
|
||||
#282
|
||||
b00000000000000000000000010001110 #
|
||||
1$
|
||||
#283
|
||||
0$
|
||||
#284
|
||||
b00000000000000000000000010001111 #
|
||||
1$
|
||||
#285
|
||||
0$
|
||||
#286
|
||||
b00000000000000000000000010010000 #
|
||||
1$
|
||||
#287
|
||||
0$
|
||||
#288
|
||||
b00000000000000000000000010010001 #
|
||||
1$
|
||||
#289
|
||||
0$
|
||||
#290
|
||||
b00000000000000000000000010010010 #
|
||||
1$
|
||||
#291
|
||||
0$
|
||||
#292
|
||||
b00000000000000000000000010010011 #
|
||||
1$
|
||||
#293
|
||||
0$
|
||||
#294
|
||||
b00000000000000000000000010010100 #
|
||||
1$
|
||||
#295
|
||||
0$
|
||||
#296
|
||||
b00000000000000000000000010010101 #
|
||||
1$
|
||||
#297
|
||||
0$
|
||||
#298
|
||||
b00000000000000000000000010010110 #
|
||||
1$
|
||||
#299
|
||||
0$
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
top_filename("t_trace_cat.v");
|
||||
|
||||
compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
vcd_identical ("$Self->{obj_dir}/simpart_0000.vcd",
|
||||
"t/$Self->{name}_0000.out");
|
||||
vcd_identical ("$Self->{obj_dir}/simpart_0100.vcd",
|
||||
"t/$Self->{name}_0100.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,265 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:40:11 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000001 #
|
||||
1$
|
||||
#1
|
||||
0$
|
||||
#2
|
||||
b00000000000000000000000000000010 #
|
||||
1$
|
||||
#3
|
||||
0$
|
||||
#4
|
||||
b00000000000000000000000000000011 #
|
||||
1$
|
||||
#5
|
||||
0$
|
||||
#6
|
||||
b00000000000000000000000000000100 #
|
||||
1$
|
||||
#7
|
||||
0$
|
||||
#8
|
||||
b00000000000000000000000000000101 #
|
||||
1$
|
||||
#9
|
||||
0$
|
||||
#10
|
||||
b00000000000000000000000000000110 #
|
||||
1$
|
||||
#11
|
||||
0$
|
||||
#12
|
||||
b00000000000000000000000000000111 #
|
||||
1$
|
||||
#13
|
||||
0$
|
||||
#14
|
||||
b00000000000000000000000000001000 #
|
||||
1$
|
||||
#15
|
||||
0$
|
||||
#16
|
||||
b00000000000000000000000000001001 #
|
||||
1$
|
||||
#17
|
||||
0$
|
||||
#18
|
||||
b00000000000000000000000000001010 #
|
||||
1$
|
||||
#19
|
||||
0$
|
||||
#20
|
||||
b00000000000000000000000000001011 #
|
||||
1$
|
||||
#21
|
||||
0$
|
||||
#22
|
||||
b00000000000000000000000000001100 #
|
||||
1$
|
||||
#23
|
||||
0$
|
||||
#24
|
||||
b00000000000000000000000000001101 #
|
||||
1$
|
||||
#25
|
||||
0$
|
||||
#26
|
||||
b00000000000000000000000000001110 #
|
||||
1$
|
||||
#27
|
||||
0$
|
||||
#28
|
||||
b00000000000000000000000000001111 #
|
||||
1$
|
||||
#29
|
||||
0$
|
||||
#30
|
||||
b00000000000000000000000000010000 #
|
||||
1$
|
||||
#31
|
||||
0$
|
||||
#32
|
||||
b00000000000000000000000000010001 #
|
||||
1$
|
||||
#33
|
||||
0$
|
||||
#34
|
||||
b00000000000000000000000000010010 #
|
||||
1$
|
||||
#35
|
||||
0$
|
||||
#36
|
||||
b00000000000000000000000000010011 #
|
||||
1$
|
||||
#37
|
||||
0$
|
||||
#38
|
||||
b00000000000000000000000000010100 #
|
||||
1$
|
||||
#39
|
||||
0$
|
||||
#40
|
||||
b00000000000000000000000000010101 #
|
||||
1$
|
||||
#41
|
||||
0$
|
||||
#42
|
||||
b00000000000000000000000000010110 #
|
||||
1$
|
||||
#43
|
||||
0$
|
||||
#44
|
||||
b00000000000000000000000000010111 #
|
||||
1$
|
||||
#45
|
||||
0$
|
||||
#46
|
||||
b00000000000000000000000000011000 #
|
||||
1$
|
||||
#47
|
||||
0$
|
||||
#48
|
||||
b00000000000000000000000000011001 #
|
||||
1$
|
||||
#49
|
||||
0$
|
||||
#50
|
||||
b00000000000000000000000000011010 #
|
||||
1$
|
||||
#51
|
||||
0$
|
||||
#52
|
||||
b00000000000000000000000000011011 #
|
||||
1$
|
||||
#53
|
||||
0$
|
||||
#54
|
||||
b00000000000000000000000000011100 #
|
||||
1$
|
||||
#55
|
||||
0$
|
||||
#56
|
||||
b00000000000000000000000000011101 #
|
||||
1$
|
||||
#57
|
||||
0$
|
||||
#58
|
||||
b00000000000000000000000000011110 #
|
||||
1$
|
||||
#59
|
||||
0$
|
||||
#60
|
||||
b00000000000000000000000000011111 #
|
||||
1$
|
||||
#61
|
||||
0$
|
||||
#62
|
||||
b00000000000000000000000000100000 #
|
||||
1$
|
||||
#63
|
||||
0$
|
||||
#64
|
||||
b00000000000000000000000000100001 #
|
||||
1$
|
||||
#65
|
||||
0$
|
||||
#66
|
||||
b00000000000000000000000000100010 #
|
||||
1$
|
||||
#67
|
||||
0$
|
||||
#68
|
||||
b00000000000000000000000000100011 #
|
||||
1$
|
||||
#69
|
||||
0$
|
||||
#70
|
||||
b00000000000000000000000000100100 #
|
||||
1$
|
||||
#71
|
||||
0$
|
||||
#72
|
||||
b00000000000000000000000000100101 #
|
||||
1$
|
||||
#73
|
||||
0$
|
||||
#74
|
||||
b00000000000000000000000000100110 #
|
||||
1$
|
||||
#75
|
||||
0$
|
||||
#76
|
||||
b00000000000000000000000000100111 #
|
||||
1$
|
||||
#77
|
||||
0$
|
||||
#78
|
||||
b00000000000000000000000000101000 #
|
||||
1$
|
||||
#79
|
||||
0$
|
||||
#80
|
||||
b00000000000000000000000000101001 #
|
||||
1$
|
||||
#81
|
||||
0$
|
||||
#82
|
||||
b00000000000000000000000000101010 #
|
||||
1$
|
||||
#83
|
||||
0$
|
||||
#84
|
||||
b00000000000000000000000000101011 #
|
||||
1$
|
||||
#85
|
||||
0$
|
||||
#86
|
||||
b00000000000000000000000000101100 #
|
||||
1$
|
||||
#87
|
||||
0$
|
||||
#88
|
||||
b00000000000000000000000000101101 #
|
||||
1$
|
||||
#89
|
||||
0$
|
||||
#90
|
||||
b00000000000000000000000000101110 #
|
||||
1$
|
||||
#91
|
||||
0$
|
||||
#92
|
||||
b00000000000000000000000000101111 #
|
||||
1$
|
||||
#93
|
||||
0$
|
||||
#94
|
||||
b00000000000000000000000000110000 #
|
||||
1$
|
||||
#95
|
||||
0$
|
||||
#96
|
||||
b00000000000000000000000000110001 #
|
||||
1$
|
||||
#97
|
||||
0$
|
||||
#98
|
||||
b00000000000000000000000000110010 #
|
||||
1$
|
||||
#99
|
||||
0$
|
||||
@@ -0,0 +1,240 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:40:11 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#100
|
||||
b00000000000000000000000000110011 #
|
||||
1$
|
||||
#101
|
||||
0$
|
||||
#102
|
||||
b00000000000000000000000000110100 #
|
||||
1$
|
||||
#103
|
||||
0$
|
||||
#104
|
||||
b00000000000000000000000000110101 #
|
||||
1$
|
||||
#105
|
||||
0$
|
||||
#106
|
||||
b00000000000000000000000000110110 #
|
||||
1$
|
||||
#107
|
||||
0$
|
||||
#108
|
||||
b00000000000000000000000000110111 #
|
||||
1$
|
||||
#109
|
||||
0$
|
||||
#110
|
||||
b00000000000000000000000000111000 #
|
||||
1$
|
||||
#111
|
||||
0$
|
||||
#112
|
||||
b00000000000000000000000000111001 #
|
||||
1$
|
||||
#113
|
||||
0$
|
||||
#114
|
||||
b00000000000000000000000000111010 #
|
||||
1$
|
||||
#115
|
||||
0$
|
||||
#116
|
||||
b00000000000000000000000000111011 #
|
||||
1$
|
||||
#117
|
||||
0$
|
||||
#118
|
||||
b00000000000000000000000000111100 #
|
||||
1$
|
||||
#119
|
||||
0$
|
||||
#120
|
||||
b00000000000000000000000000111101 #
|
||||
1$
|
||||
#121
|
||||
0$
|
||||
#122
|
||||
b00000000000000000000000000111110 #
|
||||
1$
|
||||
#123
|
||||
0$
|
||||
#124
|
||||
b00000000000000000000000000111111 #
|
||||
1$
|
||||
#125
|
||||
0$
|
||||
#126
|
||||
b00000000000000000000000001000000 #
|
||||
1$
|
||||
#127
|
||||
0$
|
||||
#128
|
||||
b00000000000000000000000001000001 #
|
||||
1$
|
||||
#129
|
||||
0$
|
||||
#130
|
||||
b00000000000000000000000001000010 #
|
||||
1$
|
||||
#131
|
||||
0$
|
||||
#132
|
||||
b00000000000000000000000001000011 #
|
||||
1$
|
||||
#133
|
||||
0$
|
||||
#134
|
||||
b00000000000000000000000001000100 #
|
||||
1$
|
||||
#135
|
||||
0$
|
||||
#136
|
||||
b00000000000000000000000001000101 #
|
||||
1$
|
||||
#137
|
||||
0$
|
||||
#138
|
||||
b00000000000000000000000001000110 #
|
||||
1$
|
||||
#139
|
||||
0$
|
||||
#140
|
||||
b00000000000000000000000001000111 #
|
||||
1$
|
||||
#141
|
||||
0$
|
||||
#142
|
||||
b00000000000000000000000001001000 #
|
||||
1$
|
||||
#143
|
||||
0$
|
||||
#144
|
||||
b00000000000000000000000001001001 #
|
||||
1$
|
||||
#145
|
||||
0$
|
||||
#146
|
||||
b00000000000000000000000001001010 #
|
||||
1$
|
||||
#147
|
||||
0$
|
||||
#148
|
||||
b00000000000000000000000001001011 #
|
||||
1$
|
||||
#149
|
||||
0$
|
||||
#150
|
||||
b00000000000000000000000001001100 #
|
||||
1$
|
||||
#151
|
||||
0$
|
||||
#152
|
||||
b00000000000000000000000001001101 #
|
||||
1$
|
||||
#153
|
||||
0$
|
||||
#154
|
||||
b00000000000000000000000001001110 #
|
||||
1$
|
||||
#155
|
||||
0$
|
||||
#156
|
||||
b00000000000000000000000001001111 #
|
||||
1$
|
||||
#157
|
||||
0$
|
||||
#158
|
||||
b00000000000000000000000001010000 #
|
||||
1$
|
||||
#159
|
||||
0$
|
||||
#160
|
||||
b00000000000000000000000001010001 #
|
||||
1$
|
||||
#161
|
||||
0$
|
||||
#162
|
||||
b00000000000000000000000001010010 #
|
||||
1$
|
||||
#163
|
||||
0$
|
||||
#164
|
||||
b00000000000000000000000001010011 #
|
||||
1$
|
||||
#165
|
||||
0$
|
||||
#166
|
||||
b00000000000000000000000001010100 #
|
||||
1$
|
||||
#167
|
||||
0$
|
||||
#168
|
||||
b00000000000000000000000001010101 #
|
||||
1$
|
||||
#169
|
||||
0$
|
||||
#170
|
||||
b00000000000000000000000001010110 #
|
||||
1$
|
||||
#171
|
||||
0$
|
||||
#172
|
||||
b00000000000000000000000001010111 #
|
||||
1$
|
||||
#173
|
||||
0$
|
||||
#174
|
||||
b00000000000000000000000001011000 #
|
||||
1$
|
||||
#175
|
||||
0$
|
||||
#176
|
||||
b00000000000000000000000001011001 #
|
||||
1$
|
||||
#177
|
||||
0$
|
||||
#178
|
||||
b00000000000000000000000001011010 #
|
||||
1$
|
||||
#179
|
||||
0$
|
||||
#180
|
||||
b00000000000000000000000001011011 #
|
||||
1$
|
||||
#181
|
||||
0$
|
||||
#182
|
||||
b00000000000000000000000001011100 #
|
||||
1$
|
||||
#183
|
||||
0$
|
||||
#184
|
||||
b00000000000000000000000001011101 #
|
||||
1$
|
||||
#185
|
||||
0$
|
||||
#186
|
||||
b00000000000000000000000001011110 #
|
||||
1$
|
||||
#187
|
||||
0$
|
||||
#188
|
||||
b00000000000000000000000001011111 #
|
||||
1$
|
||||
#189
|
||||
0$
|
||||
@@ -0,0 +1,765 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:18:07 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000001 #
|
||||
1$
|
||||
#1
|
||||
0$
|
||||
#2
|
||||
b00000000000000000000000000000010 #
|
||||
1$
|
||||
#3
|
||||
0$
|
||||
#4
|
||||
b00000000000000000000000000000011 #
|
||||
1$
|
||||
#5
|
||||
0$
|
||||
#6
|
||||
b00000000000000000000000000000100 #
|
||||
1$
|
||||
#7
|
||||
0$
|
||||
#8
|
||||
b00000000000000000000000000000101 #
|
||||
1$
|
||||
#9
|
||||
0$
|
||||
#10
|
||||
b00000000000000000000000000000110 #
|
||||
1$
|
||||
#11
|
||||
0$
|
||||
#12
|
||||
b00000000000000000000000000000111 #
|
||||
1$
|
||||
#13
|
||||
0$
|
||||
#14
|
||||
b00000000000000000000000000001000 #
|
||||
1$
|
||||
#15
|
||||
0$
|
||||
#16
|
||||
b00000000000000000000000000001001 #
|
||||
1$
|
||||
#17
|
||||
0$
|
||||
#18
|
||||
b00000000000000000000000000001010 #
|
||||
1$
|
||||
#19
|
||||
0$
|
||||
#20
|
||||
b00000000000000000000000000001011 #
|
||||
1$
|
||||
#21
|
||||
0$
|
||||
#22
|
||||
b00000000000000000000000000001100 #
|
||||
1$
|
||||
#23
|
||||
0$
|
||||
#24
|
||||
b00000000000000000000000000001101 #
|
||||
1$
|
||||
#25
|
||||
0$
|
||||
#26
|
||||
b00000000000000000000000000001110 #
|
||||
1$
|
||||
#27
|
||||
0$
|
||||
#28
|
||||
b00000000000000000000000000001111 #
|
||||
1$
|
||||
#29
|
||||
0$
|
||||
#30
|
||||
b00000000000000000000000000010000 #
|
||||
1$
|
||||
#31
|
||||
0$
|
||||
#32
|
||||
b00000000000000000000000000010001 #
|
||||
1$
|
||||
#33
|
||||
0$
|
||||
#34
|
||||
b00000000000000000000000000010010 #
|
||||
1$
|
||||
#35
|
||||
0$
|
||||
#36
|
||||
b00000000000000000000000000010011 #
|
||||
1$
|
||||
#37
|
||||
0$
|
||||
#38
|
||||
b00000000000000000000000000010100 #
|
||||
1$
|
||||
#39
|
||||
0$
|
||||
#40
|
||||
b00000000000000000000000000010101 #
|
||||
1$
|
||||
#41
|
||||
0$
|
||||
#42
|
||||
b00000000000000000000000000010110 #
|
||||
1$
|
||||
#43
|
||||
0$
|
||||
#44
|
||||
b00000000000000000000000000010111 #
|
||||
1$
|
||||
#45
|
||||
0$
|
||||
#46
|
||||
b00000000000000000000000000011000 #
|
||||
1$
|
||||
#47
|
||||
0$
|
||||
#48
|
||||
b00000000000000000000000000011001 #
|
||||
1$
|
||||
#49
|
||||
0$
|
||||
#50
|
||||
b00000000000000000000000000011010 #
|
||||
1$
|
||||
#51
|
||||
0$
|
||||
#52
|
||||
b00000000000000000000000000011011 #
|
||||
1$
|
||||
#53
|
||||
0$
|
||||
#54
|
||||
b00000000000000000000000000011100 #
|
||||
1$
|
||||
#55
|
||||
0$
|
||||
#56
|
||||
b00000000000000000000000000011101 #
|
||||
1$
|
||||
#57
|
||||
0$
|
||||
#58
|
||||
b00000000000000000000000000011110 #
|
||||
1$
|
||||
#59
|
||||
0$
|
||||
#60
|
||||
b00000000000000000000000000011111 #
|
||||
1$
|
||||
#61
|
||||
0$
|
||||
#62
|
||||
b00000000000000000000000000100000 #
|
||||
1$
|
||||
#63
|
||||
0$
|
||||
#64
|
||||
b00000000000000000000000000100001 #
|
||||
1$
|
||||
#65
|
||||
0$
|
||||
#66
|
||||
b00000000000000000000000000100010 #
|
||||
1$
|
||||
#67
|
||||
0$
|
||||
#68
|
||||
b00000000000000000000000000100011 #
|
||||
1$
|
||||
#69
|
||||
0$
|
||||
#70
|
||||
b00000000000000000000000000100100 #
|
||||
1$
|
||||
#71
|
||||
0$
|
||||
#72
|
||||
b00000000000000000000000000100101 #
|
||||
1$
|
||||
#73
|
||||
0$
|
||||
#74
|
||||
b00000000000000000000000000100110 #
|
||||
1$
|
||||
#75
|
||||
0$
|
||||
#76
|
||||
b00000000000000000000000000100111 #
|
||||
1$
|
||||
#77
|
||||
0$
|
||||
#78
|
||||
b00000000000000000000000000101000 #
|
||||
1$
|
||||
#79
|
||||
0$
|
||||
#80
|
||||
b00000000000000000000000000101001 #
|
||||
1$
|
||||
#81
|
||||
0$
|
||||
#82
|
||||
b00000000000000000000000000101010 #
|
||||
1$
|
||||
#83
|
||||
0$
|
||||
#84
|
||||
b00000000000000000000000000101011 #
|
||||
1$
|
||||
#85
|
||||
0$
|
||||
#86
|
||||
b00000000000000000000000000101100 #
|
||||
1$
|
||||
#87
|
||||
0$
|
||||
#88
|
||||
b00000000000000000000000000101101 #
|
||||
1$
|
||||
#89
|
||||
0$
|
||||
#90
|
||||
b00000000000000000000000000101110 #
|
||||
1$
|
||||
#91
|
||||
0$
|
||||
#92
|
||||
b00000000000000000000000000101111 #
|
||||
1$
|
||||
#93
|
||||
0$
|
||||
#94
|
||||
b00000000000000000000000000110000 #
|
||||
1$
|
||||
#95
|
||||
0$
|
||||
#96
|
||||
b00000000000000000000000000110001 #
|
||||
1$
|
||||
#97
|
||||
0$
|
||||
#98
|
||||
b00000000000000000000000000110010 #
|
||||
1$
|
||||
#99
|
||||
0$
|
||||
#100
|
||||
b00000000000000000000000000110011 #
|
||||
1$
|
||||
#101
|
||||
0$
|
||||
#102
|
||||
b00000000000000000000000000110100 #
|
||||
1$
|
||||
#103
|
||||
0$
|
||||
#104
|
||||
b00000000000000000000000000110101 #
|
||||
1$
|
||||
#105
|
||||
0$
|
||||
#106
|
||||
b00000000000000000000000000110110 #
|
||||
1$
|
||||
#107
|
||||
0$
|
||||
#108
|
||||
b00000000000000000000000000110111 #
|
||||
1$
|
||||
#109
|
||||
0$
|
||||
#110
|
||||
b00000000000000000000000000111000 #
|
||||
1$
|
||||
#111
|
||||
0$
|
||||
#112
|
||||
b00000000000000000000000000111001 #
|
||||
1$
|
||||
#113
|
||||
0$
|
||||
#114
|
||||
b00000000000000000000000000111010 #
|
||||
1$
|
||||
#115
|
||||
0$
|
||||
#116
|
||||
b00000000000000000000000000111011 #
|
||||
1$
|
||||
#117
|
||||
0$
|
||||
#118
|
||||
b00000000000000000000000000111100 #
|
||||
1$
|
||||
#119
|
||||
0$
|
||||
#120
|
||||
b00000000000000000000000000111101 #
|
||||
1$
|
||||
#121
|
||||
0$
|
||||
#122
|
||||
b00000000000000000000000000111110 #
|
||||
1$
|
||||
#123
|
||||
0$
|
||||
#124
|
||||
b00000000000000000000000000111111 #
|
||||
1$
|
||||
#125
|
||||
0$
|
||||
#126
|
||||
b00000000000000000000000001000000 #
|
||||
1$
|
||||
#127
|
||||
0$
|
||||
#128
|
||||
b00000000000000000000000001000001 #
|
||||
1$
|
||||
#129
|
||||
0$
|
||||
#130
|
||||
b00000000000000000000000001000010 #
|
||||
1$
|
||||
#131
|
||||
0$
|
||||
#132
|
||||
b00000000000000000000000001000011 #
|
||||
1$
|
||||
#133
|
||||
0$
|
||||
#134
|
||||
b00000000000000000000000001000100 #
|
||||
1$
|
||||
#135
|
||||
0$
|
||||
#136
|
||||
b00000000000000000000000001000101 #
|
||||
1$
|
||||
#137
|
||||
0$
|
||||
#138
|
||||
b00000000000000000000000001000110 #
|
||||
1$
|
||||
#139
|
||||
0$
|
||||
#140
|
||||
b00000000000000000000000001000111 #
|
||||
1$
|
||||
#141
|
||||
0$
|
||||
#142
|
||||
b00000000000000000000000001001000 #
|
||||
1$
|
||||
#143
|
||||
0$
|
||||
#144
|
||||
b00000000000000000000000001001001 #
|
||||
1$
|
||||
#145
|
||||
0$
|
||||
#146
|
||||
b00000000000000000000000001001010 #
|
||||
1$
|
||||
#147
|
||||
0$
|
||||
#148
|
||||
b00000000000000000000000001001011 #
|
||||
1$
|
||||
#149
|
||||
0$
|
||||
#150
|
||||
b00000000000000000000000001001100 #
|
||||
1$
|
||||
#151
|
||||
0$
|
||||
#152
|
||||
b00000000000000000000000001001101 #
|
||||
1$
|
||||
#153
|
||||
0$
|
||||
#154
|
||||
b00000000000000000000000001001110 #
|
||||
1$
|
||||
#155
|
||||
0$
|
||||
#156
|
||||
b00000000000000000000000001001111 #
|
||||
1$
|
||||
#157
|
||||
0$
|
||||
#158
|
||||
b00000000000000000000000001010000 #
|
||||
1$
|
||||
#159
|
||||
0$
|
||||
#160
|
||||
b00000000000000000000000001010001 #
|
||||
1$
|
||||
#161
|
||||
0$
|
||||
#162
|
||||
b00000000000000000000000001010010 #
|
||||
1$
|
||||
#163
|
||||
0$
|
||||
#164
|
||||
b00000000000000000000000001010011 #
|
||||
1$
|
||||
#165
|
||||
0$
|
||||
#166
|
||||
b00000000000000000000000001010100 #
|
||||
1$
|
||||
#167
|
||||
0$
|
||||
#168
|
||||
b00000000000000000000000001010101 #
|
||||
1$
|
||||
#169
|
||||
0$
|
||||
#170
|
||||
b00000000000000000000000001010110 #
|
||||
1$
|
||||
#171
|
||||
0$
|
||||
#172
|
||||
b00000000000000000000000001010111 #
|
||||
1$
|
||||
#173
|
||||
0$
|
||||
#174
|
||||
b00000000000000000000000001011000 #
|
||||
1$
|
||||
#175
|
||||
0$
|
||||
#176
|
||||
b00000000000000000000000001011001 #
|
||||
1$
|
||||
#177
|
||||
0$
|
||||
#178
|
||||
b00000000000000000000000001011010 #
|
||||
1$
|
||||
#179
|
||||
0$
|
||||
#180
|
||||
b00000000000000000000000001011011 #
|
||||
1$
|
||||
#181
|
||||
0$
|
||||
#182
|
||||
b00000000000000000000000001011100 #
|
||||
1$
|
||||
#183
|
||||
0$
|
||||
#184
|
||||
b00000000000000000000000001011101 #
|
||||
1$
|
||||
#185
|
||||
0$
|
||||
#186
|
||||
b00000000000000000000000001011110 #
|
||||
1$
|
||||
#187
|
||||
0$
|
||||
#188
|
||||
b00000000000000000000000001011111 #
|
||||
1$
|
||||
#189
|
||||
0$
|
||||
#190
|
||||
b00000000000000000000000001100000 #
|
||||
1$
|
||||
#191
|
||||
0$
|
||||
#192
|
||||
b00000000000000000000000001100001 #
|
||||
1$
|
||||
#193
|
||||
0$
|
||||
#194
|
||||
b00000000000000000000000001100010 #
|
||||
1$
|
||||
#195
|
||||
0$
|
||||
#196
|
||||
b00000000000000000000000001100011 #
|
||||
1$
|
||||
#197
|
||||
0$
|
||||
#198
|
||||
b00000000000000000000000001100100 #
|
||||
1$
|
||||
#199
|
||||
0$
|
||||
#200
|
||||
b00000000000000000000000001100101 #
|
||||
1$
|
||||
#201
|
||||
0$
|
||||
#202
|
||||
b00000000000000000000000001100110 #
|
||||
1$
|
||||
#203
|
||||
0$
|
||||
#204
|
||||
b00000000000000000000000001100111 #
|
||||
1$
|
||||
#205
|
||||
0$
|
||||
#206
|
||||
b00000000000000000000000001101000 #
|
||||
1$
|
||||
#207
|
||||
0$
|
||||
#208
|
||||
b00000000000000000000000001101001 #
|
||||
1$
|
||||
#209
|
||||
0$
|
||||
#210
|
||||
b00000000000000000000000001101010 #
|
||||
1$
|
||||
#211
|
||||
0$
|
||||
#212
|
||||
b00000000000000000000000001101011 #
|
||||
1$
|
||||
#213
|
||||
0$
|
||||
#214
|
||||
b00000000000000000000000001101100 #
|
||||
1$
|
||||
#215
|
||||
0$
|
||||
#216
|
||||
b00000000000000000000000001101101 #
|
||||
1$
|
||||
#217
|
||||
0$
|
||||
#218
|
||||
b00000000000000000000000001101110 #
|
||||
1$
|
||||
#219
|
||||
0$
|
||||
#220
|
||||
b00000000000000000000000001101111 #
|
||||
1$
|
||||
#221
|
||||
0$
|
||||
#222
|
||||
b00000000000000000000000001110000 #
|
||||
1$
|
||||
#223
|
||||
0$
|
||||
#224
|
||||
b00000000000000000000000001110001 #
|
||||
1$
|
||||
#225
|
||||
0$
|
||||
#226
|
||||
b00000000000000000000000001110010 #
|
||||
1$
|
||||
#227
|
||||
0$
|
||||
#228
|
||||
b00000000000000000000000001110011 #
|
||||
1$
|
||||
#229
|
||||
0$
|
||||
#230
|
||||
b00000000000000000000000001110100 #
|
||||
1$
|
||||
#231
|
||||
0$
|
||||
#232
|
||||
b00000000000000000000000001110101 #
|
||||
1$
|
||||
#233
|
||||
0$
|
||||
#234
|
||||
b00000000000000000000000001110110 #
|
||||
1$
|
||||
#235
|
||||
0$
|
||||
#236
|
||||
b00000000000000000000000001110111 #
|
||||
1$
|
||||
#237
|
||||
0$
|
||||
#238
|
||||
b00000000000000000000000001111000 #
|
||||
1$
|
||||
#239
|
||||
0$
|
||||
#240
|
||||
b00000000000000000000000001111001 #
|
||||
1$
|
||||
#241
|
||||
0$
|
||||
#242
|
||||
b00000000000000000000000001111010 #
|
||||
1$
|
||||
#243
|
||||
0$
|
||||
#244
|
||||
b00000000000000000000000001111011 #
|
||||
1$
|
||||
#245
|
||||
0$
|
||||
#246
|
||||
b00000000000000000000000001111100 #
|
||||
1$
|
||||
#247
|
||||
0$
|
||||
#248
|
||||
b00000000000000000000000001111101 #
|
||||
1$
|
||||
#249
|
||||
0$
|
||||
#250
|
||||
b00000000000000000000000001111110 #
|
||||
1$
|
||||
#251
|
||||
0$
|
||||
#252
|
||||
b00000000000000000000000001111111 #
|
||||
1$
|
||||
#253
|
||||
0$
|
||||
#254
|
||||
b00000000000000000000000010000000 #
|
||||
1$
|
||||
#255
|
||||
0$
|
||||
#256
|
||||
b00000000000000000000000010000001 #
|
||||
1$
|
||||
#257
|
||||
0$
|
||||
#258
|
||||
b00000000000000000000000010000010 #
|
||||
1$
|
||||
#259
|
||||
0$
|
||||
#260
|
||||
b00000000000000000000000010000011 #
|
||||
1$
|
||||
#261
|
||||
0$
|
||||
#262
|
||||
b00000000000000000000000010000100 #
|
||||
1$
|
||||
#263
|
||||
0$
|
||||
#264
|
||||
b00000000000000000000000010000101 #
|
||||
1$
|
||||
#265
|
||||
0$
|
||||
#266
|
||||
b00000000000000000000000010000110 #
|
||||
1$
|
||||
#267
|
||||
0$
|
||||
#268
|
||||
b00000000000000000000000010000111 #
|
||||
1$
|
||||
#269
|
||||
0$
|
||||
#270
|
||||
b00000000000000000000000010001000 #
|
||||
1$
|
||||
#271
|
||||
0$
|
||||
#272
|
||||
b00000000000000000000000010001001 #
|
||||
1$
|
||||
#273
|
||||
0$
|
||||
#274
|
||||
b00000000000000000000000010001010 #
|
||||
1$
|
||||
#275
|
||||
0$
|
||||
#276
|
||||
b00000000000000000000000010001011 #
|
||||
1$
|
||||
#277
|
||||
0$
|
||||
#278
|
||||
b00000000000000000000000010001100 #
|
||||
1$
|
||||
#279
|
||||
0$
|
||||
#280
|
||||
b00000000000000000000000010001101 #
|
||||
1$
|
||||
#281
|
||||
0$
|
||||
#282
|
||||
b00000000000000000000000010001110 #
|
||||
1$
|
||||
#283
|
||||
0$
|
||||
#284
|
||||
b00000000000000000000000010001111 #
|
||||
1$
|
||||
#285
|
||||
0$
|
||||
#286
|
||||
b00000000000000000000000010010000 #
|
||||
1$
|
||||
#287
|
||||
0$
|
||||
#288
|
||||
b00000000000000000000000010010001 #
|
||||
1$
|
||||
#289
|
||||
0$
|
||||
#290
|
||||
b00000000000000000000000010010010 #
|
||||
1$
|
||||
#291
|
||||
0$
|
||||
#292
|
||||
b00000000000000000000000010010011 #
|
||||
1$
|
||||
#293
|
||||
0$
|
||||
#294
|
||||
b00000000000000000000000010010100 #
|
||||
1$
|
||||
#295
|
||||
0$
|
||||
#296
|
||||
b00000000000000000000000010010101 #
|
||||
1$
|
||||
#297
|
||||
0$
|
||||
#298
|
||||
b00000000000000000000000010010110 #
|
||||
1$
|
||||
#299
|
||||
0$
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
top_filename("t_trace_cat.v");
|
||||
|
||||
compile (
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
vcd_identical ("$Self->{obj_dir}/simpart_0000.vcd",
|
||||
"t/$Self->{name}_0000.out");
|
||||
vcd_identical ("$Self->{obj_dir}/simpart_0100.vcd",
|
||||
"t/$Self->{name}_0100.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,265 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:40:11 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000001 #
|
||||
1$
|
||||
#1
|
||||
0$
|
||||
#2
|
||||
b00000000000000000000000000000010 #
|
||||
1$
|
||||
#3
|
||||
0$
|
||||
#4
|
||||
b00000000000000000000000000000011 #
|
||||
1$
|
||||
#5
|
||||
0$
|
||||
#6
|
||||
b00000000000000000000000000000100 #
|
||||
1$
|
||||
#7
|
||||
0$
|
||||
#8
|
||||
b00000000000000000000000000000101 #
|
||||
1$
|
||||
#9
|
||||
0$
|
||||
#10
|
||||
b00000000000000000000000000000110 #
|
||||
1$
|
||||
#11
|
||||
0$
|
||||
#12
|
||||
b00000000000000000000000000000111 #
|
||||
1$
|
||||
#13
|
||||
0$
|
||||
#14
|
||||
b00000000000000000000000000001000 #
|
||||
1$
|
||||
#15
|
||||
0$
|
||||
#16
|
||||
b00000000000000000000000000001001 #
|
||||
1$
|
||||
#17
|
||||
0$
|
||||
#18
|
||||
b00000000000000000000000000001010 #
|
||||
1$
|
||||
#19
|
||||
0$
|
||||
#20
|
||||
b00000000000000000000000000001011 #
|
||||
1$
|
||||
#21
|
||||
0$
|
||||
#22
|
||||
b00000000000000000000000000001100 #
|
||||
1$
|
||||
#23
|
||||
0$
|
||||
#24
|
||||
b00000000000000000000000000001101 #
|
||||
1$
|
||||
#25
|
||||
0$
|
||||
#26
|
||||
b00000000000000000000000000001110 #
|
||||
1$
|
||||
#27
|
||||
0$
|
||||
#28
|
||||
b00000000000000000000000000001111 #
|
||||
1$
|
||||
#29
|
||||
0$
|
||||
#30
|
||||
b00000000000000000000000000010000 #
|
||||
1$
|
||||
#31
|
||||
0$
|
||||
#32
|
||||
b00000000000000000000000000010001 #
|
||||
1$
|
||||
#33
|
||||
0$
|
||||
#34
|
||||
b00000000000000000000000000010010 #
|
||||
1$
|
||||
#35
|
||||
0$
|
||||
#36
|
||||
b00000000000000000000000000010011 #
|
||||
1$
|
||||
#37
|
||||
0$
|
||||
#38
|
||||
b00000000000000000000000000010100 #
|
||||
1$
|
||||
#39
|
||||
0$
|
||||
#40
|
||||
b00000000000000000000000000010101 #
|
||||
1$
|
||||
#41
|
||||
0$
|
||||
#42
|
||||
b00000000000000000000000000010110 #
|
||||
1$
|
||||
#43
|
||||
0$
|
||||
#44
|
||||
b00000000000000000000000000010111 #
|
||||
1$
|
||||
#45
|
||||
0$
|
||||
#46
|
||||
b00000000000000000000000000011000 #
|
||||
1$
|
||||
#47
|
||||
0$
|
||||
#48
|
||||
b00000000000000000000000000011001 #
|
||||
1$
|
||||
#49
|
||||
0$
|
||||
#50
|
||||
b00000000000000000000000000011010 #
|
||||
1$
|
||||
#51
|
||||
0$
|
||||
#52
|
||||
b00000000000000000000000000011011 #
|
||||
1$
|
||||
#53
|
||||
0$
|
||||
#54
|
||||
b00000000000000000000000000011100 #
|
||||
1$
|
||||
#55
|
||||
0$
|
||||
#56
|
||||
b00000000000000000000000000011101 #
|
||||
1$
|
||||
#57
|
||||
0$
|
||||
#58
|
||||
b00000000000000000000000000011110 #
|
||||
1$
|
||||
#59
|
||||
0$
|
||||
#60
|
||||
b00000000000000000000000000011111 #
|
||||
1$
|
||||
#61
|
||||
0$
|
||||
#62
|
||||
b00000000000000000000000000100000 #
|
||||
1$
|
||||
#63
|
||||
0$
|
||||
#64
|
||||
b00000000000000000000000000100001 #
|
||||
1$
|
||||
#65
|
||||
0$
|
||||
#66
|
||||
b00000000000000000000000000100010 #
|
||||
1$
|
||||
#67
|
||||
0$
|
||||
#68
|
||||
b00000000000000000000000000100011 #
|
||||
1$
|
||||
#69
|
||||
0$
|
||||
#70
|
||||
b00000000000000000000000000100100 #
|
||||
1$
|
||||
#71
|
||||
0$
|
||||
#72
|
||||
b00000000000000000000000000100101 #
|
||||
1$
|
||||
#73
|
||||
0$
|
||||
#74
|
||||
b00000000000000000000000000100110 #
|
||||
1$
|
||||
#75
|
||||
0$
|
||||
#76
|
||||
b00000000000000000000000000100111 #
|
||||
1$
|
||||
#77
|
||||
0$
|
||||
#78
|
||||
b00000000000000000000000000101000 #
|
||||
1$
|
||||
#79
|
||||
0$
|
||||
#80
|
||||
b00000000000000000000000000101001 #
|
||||
1$
|
||||
#81
|
||||
0$
|
||||
#82
|
||||
b00000000000000000000000000101010 #
|
||||
1$
|
||||
#83
|
||||
0$
|
||||
#84
|
||||
b00000000000000000000000000101011 #
|
||||
1$
|
||||
#85
|
||||
0$
|
||||
#86
|
||||
b00000000000000000000000000101100 #
|
||||
1$
|
||||
#87
|
||||
0$
|
||||
#88
|
||||
b00000000000000000000000000101101 #
|
||||
1$
|
||||
#89
|
||||
0$
|
||||
#90
|
||||
b00000000000000000000000000101110 #
|
||||
1$
|
||||
#91
|
||||
0$
|
||||
#92
|
||||
b00000000000000000000000000101111 #
|
||||
1$
|
||||
#93
|
||||
0$
|
||||
#94
|
||||
b00000000000000000000000000110000 #
|
||||
1$
|
||||
#95
|
||||
0$
|
||||
#96
|
||||
b00000000000000000000000000110001 #
|
||||
1$
|
||||
#97
|
||||
0$
|
||||
#98
|
||||
b00000000000000000000000000110010 #
|
||||
1$
|
||||
#99
|
||||
0$
|
||||
@@ -0,0 +1,240 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Sat Feb 23 20:40:11 2013
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 $ clk $end
|
||||
$scope module v $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#100
|
||||
b00000000000000000000000000110011 #
|
||||
1$
|
||||
#101
|
||||
0$
|
||||
#102
|
||||
b00000000000000000000000000110100 #
|
||||
1$
|
||||
#103
|
||||
0$
|
||||
#104
|
||||
b00000000000000000000000000110101 #
|
||||
1$
|
||||
#105
|
||||
0$
|
||||
#106
|
||||
b00000000000000000000000000110110 #
|
||||
1$
|
||||
#107
|
||||
0$
|
||||
#108
|
||||
b00000000000000000000000000110111 #
|
||||
1$
|
||||
#109
|
||||
0$
|
||||
#110
|
||||
b00000000000000000000000000111000 #
|
||||
1$
|
||||
#111
|
||||
0$
|
||||
#112
|
||||
b00000000000000000000000000111001 #
|
||||
1$
|
||||
#113
|
||||
0$
|
||||
#114
|
||||
b00000000000000000000000000111010 #
|
||||
1$
|
||||
#115
|
||||
0$
|
||||
#116
|
||||
b00000000000000000000000000111011 #
|
||||
1$
|
||||
#117
|
||||
0$
|
||||
#118
|
||||
b00000000000000000000000000111100 #
|
||||
1$
|
||||
#119
|
||||
0$
|
||||
#120
|
||||
b00000000000000000000000000111101 #
|
||||
1$
|
||||
#121
|
||||
0$
|
||||
#122
|
||||
b00000000000000000000000000111110 #
|
||||
1$
|
||||
#123
|
||||
0$
|
||||
#124
|
||||
b00000000000000000000000000111111 #
|
||||
1$
|
||||
#125
|
||||
0$
|
||||
#126
|
||||
b00000000000000000000000001000000 #
|
||||
1$
|
||||
#127
|
||||
0$
|
||||
#128
|
||||
b00000000000000000000000001000001 #
|
||||
1$
|
||||
#129
|
||||
0$
|
||||
#130
|
||||
b00000000000000000000000001000010 #
|
||||
1$
|
||||
#131
|
||||
0$
|
||||
#132
|
||||
b00000000000000000000000001000011 #
|
||||
1$
|
||||
#133
|
||||
0$
|
||||
#134
|
||||
b00000000000000000000000001000100 #
|
||||
1$
|
||||
#135
|
||||
0$
|
||||
#136
|
||||
b00000000000000000000000001000101 #
|
||||
1$
|
||||
#137
|
||||
0$
|
||||
#138
|
||||
b00000000000000000000000001000110 #
|
||||
1$
|
||||
#139
|
||||
0$
|
||||
#140
|
||||
b00000000000000000000000001000111 #
|
||||
1$
|
||||
#141
|
||||
0$
|
||||
#142
|
||||
b00000000000000000000000001001000 #
|
||||
1$
|
||||
#143
|
||||
0$
|
||||
#144
|
||||
b00000000000000000000000001001001 #
|
||||
1$
|
||||
#145
|
||||
0$
|
||||
#146
|
||||
b00000000000000000000000001001010 #
|
||||
1$
|
||||
#147
|
||||
0$
|
||||
#148
|
||||
b00000000000000000000000001001011 #
|
||||
1$
|
||||
#149
|
||||
0$
|
||||
#150
|
||||
b00000000000000000000000001001100 #
|
||||
1$
|
||||
#151
|
||||
0$
|
||||
#152
|
||||
b00000000000000000000000001001101 #
|
||||
1$
|
||||
#153
|
||||
0$
|
||||
#154
|
||||
b00000000000000000000000001001110 #
|
||||
1$
|
||||
#155
|
||||
0$
|
||||
#156
|
||||
b00000000000000000000000001001111 #
|
||||
1$
|
||||
#157
|
||||
0$
|
||||
#158
|
||||
b00000000000000000000000001010000 #
|
||||
1$
|
||||
#159
|
||||
0$
|
||||
#160
|
||||
b00000000000000000000000001010001 #
|
||||
1$
|
||||
#161
|
||||
0$
|
||||
#162
|
||||
b00000000000000000000000001010010 #
|
||||
1$
|
||||
#163
|
||||
0$
|
||||
#164
|
||||
b00000000000000000000000001010011 #
|
||||
1$
|
||||
#165
|
||||
0$
|
||||
#166
|
||||
b00000000000000000000000001010100 #
|
||||
1$
|
||||
#167
|
||||
0$
|
||||
#168
|
||||
b00000000000000000000000001010101 #
|
||||
1$
|
||||
#169
|
||||
0$
|
||||
#170
|
||||
b00000000000000000000000001010110 #
|
||||
1$
|
||||
#171
|
||||
0$
|
||||
#172
|
||||
b00000000000000000000000001010111 #
|
||||
1$
|
||||
#173
|
||||
0$
|
||||
#174
|
||||
b00000000000000000000000001011000 #
|
||||
1$
|
||||
#175
|
||||
0$
|
||||
#176
|
||||
b00000000000000000000000001011001 #
|
||||
1$
|
||||
#177
|
||||
0$
|
||||
#178
|
||||
b00000000000000000000000001011010 #
|
||||
1$
|
||||
#179
|
||||
0$
|
||||
#180
|
||||
b00000000000000000000000001011011 #
|
||||
1$
|
||||
#181
|
||||
0$
|
||||
#182
|
||||
b00000000000000000000000001011100 #
|
||||
1$
|
||||
#183
|
||||
0$
|
||||
#184
|
||||
b00000000000000000000000001011101 #
|
||||
1$
|
||||
#185
|
||||
0$
|
||||
#186
|
||||
b00000000000000000000000001011110 #
|
||||
1$
|
||||
#187
|
||||
0$
|
||||
#188
|
||||
b00000000000000000000000001011111 #
|
||||
1$
|
||||
#189
|
||||
0$
|
||||
@@ -11,7 +11,7 @@ compile (
|
||||
fails=>$Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_tri_pull2_bad.v:\d+: Unsupported: Conflicting pull directions.
|
||||
%Error: t/t_tri_pull2_bad.v:\d+: ... Location of conflicing pull.
|
||||
%Error: t/t_tri_pull2_bad.v:\d+: ... Location of conflicting pull.
|
||||
%Error: Exiting due to',
|
||||
);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ compile (
|
||||
fails=>$Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_tri_pull_bad.v:\d+: Unsupported: Conflicting pull directions.
|
||||
%Error: t/t_tri_pull_bad.v:\d+: ... Location of conflicing pull.
|
||||
%Error: t/t_tri_pull_bad.v:\d+: ... Location of conflicting pull.
|
||||
%Error: Exiting due to',
|
||||
);
|
||||
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,31 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jue Xu.
|
||||
|
||||
// bug630
|
||||
|
||||
module t ( clk, out );
|
||||
input clk;
|
||||
output out;
|
||||
|
||||
reg a;
|
||||
reg b;
|
||||
|
||||
typedef struct packed {
|
||||
logic config_a;
|
||||
logic config_b;
|
||||
} param_t;
|
||||
// verilator lint_off UNOPTFLAT
|
||||
param_t conf [1:2] ;
|
||||
// verilator lint_on UNOPTFLAT
|
||||
|
||||
always @ (posedge clk) begin
|
||||
conf[2].config_b <= a;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
always @ (posedge conf[2].config_b) begin
|
||||
a = conf[2].config_a;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,32 @@
|
||||
// DESCRIPTION: Verilator: Simple test of unoptflat
|
||||
//
|
||||
// Simple demonstration of an UNOPTFLAT combinatorial loop, using just 2 bits.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jeremy Bennett.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
wire [1:0] x = { x[0], clk };
|
||||
|
||||
initial begin
|
||||
x = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge clk) begin
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("x = %x\n", x);
|
||||
`endif
|
||||
|
||||
if (x[1] != 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,35 @@
|
||||
// DESCRIPTION: Verilator: Simple test of unoptflat
|
||||
//
|
||||
// Simple demonstration of an UNOPTFLAT combinatorial loop, using 3 bits.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jeremy Bennett.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
wire [2:0] x;
|
||||
|
||||
initial begin
|
||||
x = 3'b000;
|
||||
end
|
||||
|
||||
assign x[1:0] = { x[0], clk };
|
||||
assign x[2:1] = { clk, x[1] };
|
||||
|
||||
always @(posedge clk or negedge clk) begin
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("x = %x\n", x);
|
||||
`endif
|
||||
|
||||
if (x[1] != 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // t
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_unoptflat_simple_2.v");
|
||||
|
||||
# Compile only
|
||||
compile (
|
||||
verilator_flags2 => ["--report-unoptflat"],
|
||||
fails => 1,
|
||||
expect=>
|
||||
'.*%Warning-UNOPTFLAT: Widest candidate vars to split:
|
||||
%Warning-UNOPTFLAT: t/t_unoptflat_simple_2.v:\d+: v.x, width 3, fanout 12
|
||||
.*%Error: Exiting due to ',
|
||||
);
|
||||
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,79 @@
|
||||
// DESCRIPTION: Verilator: Simple test of unoptflat
|
||||
//
|
||||
// Demonstration of an UNOPTFLAT combinatorial loop using 3 bits and looping
|
||||
// through 2 sub-modules.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Jeremy Bennett.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
wire [2:0] x;
|
||||
|
||||
initial begin
|
||||
x = 3'b000;
|
||||
end
|
||||
|
||||
test1 test1i ( .clk (clk),
|
||||
.xvecin (x[1:0]),
|
||||
.xvecout (x[2:1]));
|
||||
|
||||
test2 test2i ( .clk (clk),
|
||||
.xvecin (x[2:1]),
|
||||
.xvecout (x[1:0]));
|
||||
|
||||
always @(posedge clk or negedge clk) begin
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("x = %x\n", x);
|
||||
`endif
|
||||
|
||||
if (x[1] != 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // t
|
||||
|
||||
|
||||
module test1
|
||||
(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk,
|
||||
xvecin,
|
||||
// Outputs
|
||||
xvecout
|
||||
);
|
||||
|
||||
input clk;
|
||||
input wire [1:0] xvecin;
|
||||
|
||||
output wire [1:0] xvecout;
|
||||
|
||||
assign xvecout = {xvecin[0], clk};
|
||||
|
||||
endmodule // test
|
||||
|
||||
|
||||
module test2
|
||||
(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk,
|
||||
xvecin,
|
||||
// Outputs
|
||||
xvecout
|
||||
);
|
||||
|
||||
input clk;
|
||||
input wire [1:0] xvecin;
|
||||
|
||||
output wire [1:0] xvecout;
|
||||
|
||||
assign xvecout = {clk, xvecin[1]};
|
||||
|
||||
endmodule // test
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_unoptflat_simple_3.v");
|
||||
|
||||
# Compile only
|
||||
compile (
|
||||
fails => 1
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
top_filename("t/t_unoptflat_simple.v");
|
||||
|
||||
# Compile only
|
||||
compile (
|
||||
fails => 1
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Reference in New Issue
Block a user