Add --trace-structs to show struct names, bug673.

This commit is contained in:
Wilson Snyder 2013-12-14 19:13:31 -05:00
parent f571658aa4
commit 801b718953
11 changed files with 519 additions and 16 deletions

View File

@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.855 devel
*** Add --trace-structs to show struct names, bug673. [Chris Randall]
**** Fix tracing of packed structs, bug705. [Jie Xu]
**** Fix --lint-only with MinGW, msg1283. [HyungKi Jeong]

View File

@ -325,6 +325,7 @@ descriptions in the next sections for more information.
--trace-depth <levels> Depth of tracing
--trace-max-array <depth> Maximum bit width for tracing
--trace-max-width <width> Maximum array depth for tracing
--trace-structs Enable tracing structure names
--trace-underscore Enable tracing of _signals
-U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations
@ -1021,6 +1022,13 @@ Rarely needed. Specify the maximum bit width of a signal that may be
traced. Defaults to 256, as tracing large vectors may greatly slow traced
simulations.
=item --trace-structs
Enable tracing to show the name of packed structure, union, and packed
array fields, rather than a simgle combined packed bus. Due to VCD file
format constraints this may result in significantly slower trace times and
larger trace files.
=item --trace-underscore
Enable tracing of signals that start with an underscore. Normally, these

View File

@ -144,6 +144,12 @@ private:
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstMemberDType* nodep, AstNUser*) {
// Keep member names iff upper type exists
nodep->iterateChildren(*this);
// No checkDType(nodep)
checkAll(nodep);
}
virtual void visit(AstNodeDType* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkDType(nodep);

View File

@ -756,6 +756,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( !strcmp (sw, "-sv") ) { m_defaultLanguage = V3LangCode::L1800_2005; }
else if ( onoff (sw, "-trace", flag/*ref*/) ) { m_trace = flag; }
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
else if ( onoff (sw, "-trace-structs", flag/*ref*/) ) { m_traceStructs = flag; }
else if ( onoff (sw, "-trace-underscore", flag/*ref*/) ) { m_traceUnderscore = flag; }
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Undocumented, old Verilator-2
else if ( onoff (sw, "-x-initial-edge", flag/*ref*/) ) { m_xInitialEdge = flag; }
@ -1222,6 +1223,7 @@ V3Options::V3Options() {
m_systemPerl = false;
m_trace = false;
m_traceDups = false;
m_traceStructs = false;
m_traceUnderscore = false;
m_underlineZero = false;
m_reportUnoptflat = false;

View File

@ -90,6 +90,7 @@ class V3Options {
bool m_stats; // main switch: --stats
bool m_trace; // main switch: --trace
bool m_traceDups; // main switch: --trace-dups
bool m_traceStructs; // main switch: --trace-structs
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
@ -214,6 +215,7 @@ class V3Options {
bool exe() const { return m_exe; }
bool trace() const { return m_trace; }
bool traceDups() const { return m_traceDups; }
bool traceStructs() const { return m_traceStructs; }
bool traceUnderscore() const { return m_traceUnderscore; }
bool orderClockDly() const { return m_orderClockDly; }
bool outFormatOk() const { return m_outFormatOk; }

View File

@ -221,26 +221,59 @@ private:
}
virtual void visit(AstPackArrayDType* nodep, AstNUser*) {
if (m_traVscp) {
// Everything downstream is packed, so deal with as one trace unit
// This may not be the nicest for user presentation, but is a much faster way to trace
addTraceDecl(VNumRange());
}
}
virtual void visit(AstNodeClassDType* nodep, AstNUser*) {
if (m_traVscp) {
if (nodep->packed()) {
if (!v3Global.opt.traceStructs()) {
// Everything downstream is packed, so deal with as one trace unit
// This may not be the nicest for user presentation, but is a much faster way to trace
addTraceDecl(VNumRange());
} else {
addIgnore("Unsupported: Unpacked struct/union");
// Once we have an UnpackedMemberSel which works, this code is straight forward:
//for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
// AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
// ...
// m_traShowname += string(" ")+itemp->name();
// m_traValuep = new AstMemberSel(nodep->fileline(), m_traValuep->cloneTree(true), ...
// and iterate
AstNodeDType* subtypep = nodep->subDTypep()->skipRefp();
for (int i=nodep->lsb(); i<=nodep->msb(); ++i) {
string oldShowname = m_traShowname;
AstNode* oldValuep = m_traValuep;
{
m_traShowname += string("(")+cvtToStr(i)+string(")");
m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
(i - nodep->lsb())*subtypep->width(),
subtypep->width());
subtypep->accept(*this);
m_traValuep->deleteTree(); m_traValuep = NULL;
}
m_traShowname = oldShowname;
m_traValuep = oldValuep;
}
}
}
}
virtual void visit(AstNodeClassDType* nodep, AstNUser*) {
if (m_traVscp) {
if (nodep->packed() && !v3Global.opt.traceStructs()) {
// Everything downstream is packed, so deal with as one trace unit
// This may not be the nicest for user presentation, but is a much faster way to trace
addTraceDecl(VNumRange());
} else {
if (!nodep->packed()) {
addIgnore("Unsupported: Unpacked struct/union");
} else {
for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
string oldShowname = m_traShowname;
AstNode* oldValuep = m_traValuep;
{
m_traShowname += string(" ")+itemp->prettyName();
m_traValuep->dumpTree(cout, "-tv: ");
if (nodep->castStructDType()) {
m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
itemp->lsb(), subtypep->width());
subtypep->accept(*this);
m_traValuep->deleteTree(); m_traValuep = NULL;
} else { // Else union, replicate fields
subtypep->accept(*this);
}
}
m_traShowname = oldShowname;
m_traValuep = oldValuep;
}
}
}
}
}

View File

@ -0,0 +1,148 @@
$version Generated by VerilatedVcd $end
$date Sat Dec 14 19:07:34 2013
$end
$timescale 1ns $end
$scope module top $end
$var wire 1 0 clk $end
$scope module v $end
$var wire 1 0 clk $end
$var wire 32 # cyc [31:0] $end
$var wire 2 ' v_arrp [2:1] $end
$var wire 2 ( v_arrp_arrp [2:1] $end
$var wire 2 ) v_arrp_strp [1:0] $end
$var wire 1 1 v_arru(1) $end
$var wire 1 2 v_arru(2) $end
$var wire 2 * v_arru_arrp(3) [2:1] $end
$var wire 2 + v_arru_arrp(4) [2:1] $end
$var wire 1 3 v_arru_arru(3)(1) $end
$var wire 1 4 v_arru_arru(3)(2) $end
$var wire 1 5 v_arru_arru(4)(1) $end
$var wire 1 6 v_arru_arru(4)(2) $end
$var wire 2 , v_arru_strp(3) [1:0] $end
$var wire 2 - v_arru_strp(4) [1:0] $end
$var wire 2 $ v_strp [1:0] $end
$var wire 4 % v_strp_strp [3:0] $end
$var wire 2 & v_unip_strp [1:0] $end
$scope module unnamedblk1 $end
$var wire 32 . b [31:0] $end
$scope module unnamedblk2 $end
$var wire 32 / a [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 #
b00 $
b0000 %
b00 &
b00 '
b0000 (
b0000 )
b00 *
b00 +
b00 ,
b00 -
b00000000000000000000000000000000 .
b00000000000000000000000000000000 /
00
01
02
03
04
05
06
#10
b00000000000000000000000000000001 #
b11 $
b1111 %
b11 &
b11 '
b1111 (
b1111 )
b11 *
b11 +
b11 ,
b11 -
b00000000000000000000000000000101 .
b00000000000000000000000000000101 /
10
#15
00
#20
b00000000000000000000000000000010 #
b00 $
b0000 %
b00 &
b00 '
b0000 (
b0000 )
b00 *
b00 +
b00 ,
b00 -
10
#25
00
#30
b00000000000000000000000000000011 #
b11 $
b1111 %
b11 &
b11 '
b1111 (
b1111 )
b11 *
b11 +
b11 ,
b11 -
10
#35
00
#40
b00000000000000000000000000000100 #
b00 $
b0000 %
b00 &
b00 '
b0000 (
b0000 )
b00 *
b00 +
b00 ,
b00 -
10
#45
00
#50
b00000000000000000000000000000101 #
b11 $
b1111 %
b11 &
b11 '
b1111 (
b1111 )
b11 *
b11 +
b11 ,
b11 -
10
#55
00
#60
b00000000000000000000000000000110 #
b00 $
b0000 %
b00 &
b00 '
b0000 (
b0000 )
b00 *
b00 +
b00 ,
b00 -
10

View File

@ -25,5 +25,7 @@ file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arru\(/);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arrp\(/);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_strp\(/);
vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out");
ok(1);
1;

View File

@ -17,6 +17,11 @@ module t (clk);
strp_t x0;
} strp_strp_t;
typedef union packed {
strp_t x1;
strp_t x0;
} unip_strp_t;
typedef bit [2:1] arrp_t;
typedef arrp_t [4:3] arrp_arrp_t;
@ -29,6 +34,7 @@ module t (clk);
strp_t v_strp;
strp_strp_t v_strp_strp;
unip_strp_t v_unip_strp;
arrp_t v_arrp;
arrp_arrp_t v_arrp_arrp;
arrp_strp_t v_arrp_strp;
@ -41,6 +47,7 @@ module t (clk);
cyc <= cyc + 1;
v_strp <= ~v_strp;
v_strp_strp <= ~v_strp_strp;
v_unip_strp <= ~v_unip_strp;
v_arrp_strp <= ~v_arrp_strp;
v_arrp <= ~v_arrp;
v_arrp_arrp <= ~v_arrp_arrp;

View File

@ -0,0 +1,260 @@
$version Generated by VerilatedVcd $end
$date Sat Dec 14 18:56:47 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
$var wire 2 , v_arrp [2:1] $end
$var wire 2 - v_arrp_arrp(3) [1:0] $end
$var wire 2 . v_arrp_arrp(4) [1:0] $end
$var wire 1 < v_arru(1) $end
$var wire 1 = v_arru(2) $end
$var wire 2 3 v_arru_arrp(3) [2:1] $end
$var wire 2 4 v_arru_arrp(4) [2:1] $end
$var wire 1 > v_arru_arru(3)(1) $end
$var wire 1 ? v_arru_arru(3)(2) $end
$var wire 1 @ v_arru_arru(4)(1) $end
$var wire 1 A v_arru_arru(4)(2) $end
$scope module unnamedblk1 $end
$var wire 32 9 b [31:0] $end
$scope module unnamedblk2 $end
$var wire 32 : a [31:0] $end
$upscope $end
$upscope $end
$scope module v_arrp_strp(3) $end
$var wire 1 0 b0 $end
$var wire 1 / b1 $end
$upscope $end
$scope module v_arrp_strp(4) $end
$var wire 1 2 b0 $end
$var wire 1 1 b1 $end
$upscope $end
$scope module v_arru_strp(3) $end
$var wire 1 6 b0 $end
$var wire 1 5 b1 $end
$upscope $end
$scope module v_arru_strp(4) $end
$var wire 1 8 b0 $end
$var wire 1 7 b1 $end
$upscope $end
$scope module v_strp $end
$var wire 1 % b0 $end
$var wire 1 $ b1 $end
$upscope $end
$scope module v_strp_strp $end
$scope module x0 $end
$var wire 1 ) b0 $end
$var wire 1 ( b1 $end
$upscope $end
$scope module x1 $end
$var wire 1 ' b0 $end
$var wire 1 & b1 $end
$upscope $end
$upscope $end
$scope module v_unip_strp $end
$scope module x0 $end
$var wire 1 + b0 $end
$var wire 1 * b1 $end
$upscope $end
$scope module x1 $end
$var wire 1 + b0 $end
$var wire 1 * b1 $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 #
0$
0%
0&
0'
0(
0)
0*
0+
b00 ,
b00 -
b00 .
0/
00
01
02
b00 3
b00 4
05
06
07
08
b00000000000000000000000000000000 9
b00000000000000000000000000000000 :
0;
0<
0=
0>
0?
0@
0A
#10
b00000000000000000000000000000001 #
1$
1%
1&
1'
1(
1)
1*
1+
b11 ,
b11 -
b11 .
1/
10
11
12
b11 3
b11 4
15
16
17
18
b00000000000000000000000000000101 9
b00000000000000000000000000000101 :
1;
#15
0;
#20
b00000000000000000000000000000010 #
0$
0%
0&
0'
0(
0)
0*
0+
b00 ,
b00 -
b00 .
0/
00
01
02
b00 3
b00 4
05
06
07
08
1;
#25
0;
#30
b00000000000000000000000000000011 #
1$
1%
1&
1'
1(
1)
1*
1+
b11 ,
b11 -
b11 .
1/
10
11
12
b11 3
b11 4
15
16
17
18
1;
#35
0;
#40
b00000000000000000000000000000100 #
0$
0%
0&
0'
0(
0)
0*
0+
b00 ,
b00 -
b00 .
0/
00
01
02
b00 3
b00 4
05
06
07
08
1;
#45
0;
#50
b00000000000000000000000000000101 #
1$
1%
1&
1'
1(
1)
1*
1+
b11 ,
b11 -
b11 .
1/
10
11
12
b11 3
b11 4
15
16
17
18
1;
#55
0;
#60
b00000000000000000000000000000110 #
0$
0%
0&
0'
0(
0)
0*
0+
b00 ,
b00 -
b00 .
0/
00
01
02
b00 3
b00 4
05
06
07
08
1;

View File

@ -0,0 +1,33 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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_trace_complex.v");
compile (
verilator_flags2 => ['--cc --trace --trace-structs'],
);
execute (
check_finished=>1,
);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp /);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp_strp /);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp /);
file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_arrp /);
file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_strp /);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru\(/);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arru\(/);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arrp\(/);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_strp\(/);
vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out");
ok(1);
1;