Add /*verilator tag*/ for XML extraction applications.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Chris Randall 2017-10-06 07:33:52 -04:00 committed by Wilson Snyder
parent ba270e09a4
commit 264b888ef2
11 changed files with 117 additions and 1 deletions

View File

@ -13,6 +13,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Add --no-relative-cfuncs and related default optimization, bug1224. [John Coiner]
*** Add /*verilator tag*/ for XML extraction applications. [Chris Randall]
**** The internal test_verilated test directory is moved to be part of test_regress.
**** Fix over-aggressive inlining, bug1223. [John Coiner]

View File

@ -2574,6 +2574,12 @@ indicate the function or task should pass all remaining arguments through
$sformatf. This allows creation of DPI functions with $display like
behavior. See the test_regress/t/t_dpi_display.v file for an example.
=item /*verilator tag <text...>*/
Attached after a variable or structure member to indicate opaque (to
Verilator) text that should be passed through to the XML output as a tag,
for use by downstream applications.
=item /*verilator tracing_off*/
Disable waveform tracing for all future signals that are declared in this

View File

@ -1087,6 +1087,8 @@ public:
// ACCESSORS
virtual string name() const { return ""; }
virtual void name(const string& name) { this->v3fatalSrc("name() called on object without name() method"); }
virtual void tag(const string& text) {}
virtual string tag() const { return ""; }
virtual string verilogKwd() const { return ""; }
string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed

View File

@ -610,6 +610,7 @@ class AstMemberDType : public AstNodeDType {
private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
string m_name; // Name of variable
string m_tag; // Holds the string of the verilator tag -- used in XML output.
int m_lsb; // Within this level's packed struct, the LSB of the first bit of the member
//UNSUP: int m_randType; // Randomization type (IEEE)
public:
@ -650,6 +651,8 @@ public:
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual void tag(const string& text) { m_tag = text;}
virtual string tag() const { return m_tag; }
int lsb() const { return m_lsb; }
void lsb(int lsb) { m_lsb=lsb; }
};
@ -978,6 +981,7 @@ class AstVar : public AstNode {
private:
string m_name; // Name of variable
string m_origName; // Original name before dot addition
string m_tag; // Holds the string of the verilator tag -- used in XML output.
AstVarType m_varType; // Type of variable
bool m_input:1; // Input or inout
bool m_output:1; // Output or inout
@ -1118,6 +1122,8 @@ public:
void trace(bool flag) { m_trace=flag; }
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual void tag(const string& text) { m_tag = text;}
virtual string tag() const { return m_tag; }
virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input"
: isOutput() ? "output" : varType().ascii()); }
bool isInput() const { return m_input; }

View File

@ -68,6 +68,7 @@ class EmitXmlFileVisitor : public AstNVisitor {
if (tag=="") tag = VString::downcase(nodep->typeName());
puts("<"+tag+" "+nodep->fileline()->xml());
if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); }
if (nodep->tag()!="") { puts(" tag="); putsQuoted(nodep->tag()); }
}
void outputChildrenEnd(AstNode* nodep, string tag) {
if (tag=="") tag = VString::downcase(nodep->typeName());

View File

@ -119,6 +119,8 @@ class V3ParseImp {
deque<FileLine> m_lintState; // Current lint state for save/restore
deque<string> m_ppBuffers; // Preprocessor->lex buffer of characters to process
string m_tag; // Contents (if any) of current verilator tag
AstNode* m_tagNodep; // Points to the node to set to m_tag or NULL to not set.
public:
// Note these are an exception to using the filename as the debug type
static int debugBison() {
@ -143,6 +145,10 @@ public:
void verilatorCmtLintSave();
void verilatorCmtLintRestore();
void verilatorCmtBad(const char* text);
void tag(const char* text);
void tagNodep(AstNode* nodep) { m_tagNodep = nodep; }
AstNode* tagNodep() const { return m_tagNodep;}
static double parseDouble(const char* text, size_t length, bool* successp = NULL);
void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; }
bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; }
@ -218,6 +224,7 @@ public:
m_curBisonVal.token = 0;
m_prevBisonVal.token = 0;
// m_aheadVal not used as m_ahead = false
m_tagNodep = NULL;
}
~V3ParseImp();
void parserClear();

View File

@ -102,6 +102,15 @@ void V3ParseImp::verilatorCmtBad(const char* textp) {
}
}
void V3ParseImp::tag(const char* text) {
if (m_tagNodep) {
string tmp = text + strlen("/*verilator tag ");
string::size_type pos;
if ((pos=tmp.rfind("*/")) != string::npos) { tmp.erase(pos); }
m_tagNodep->tag(tmp);
}
}
// See V3Read.cpp
//void V3ParseImp::statePop() { yy_pop_state(); }
@ -702,6 +711,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"/*verilator lint_on"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, false); }
"/*verilator lint_restore*/" {PARSEP->verilatorCmtLintRestore(); }
"/*verilator lint_save*/" {PARSEP->verilatorCmtLintSave(); }
"/*verilator tag"[^*]*"*/" {PARSEP->tag(yytext); }
"/**/" { }
"/*"[^*]+"*/" {PARSEP->verilatorCmtBad(yytext); }

View File

@ -1425,7 +1425,9 @@ member_decl_assignment<memberp>: // Derived from IEEE: variable_decl_assignment
// // At present we allow only packed structures/unions. So this is different from variable_decl_assignment
id variable_dimensionListE
{ if ($2) $2->v3error("Unsupported: Unpacked array in packed struct/union");
$$ = new AstMemberDType($<fl>1, *$1, VFlagChildDType(), GRAMMARP->m_memDTypep->cloneTree(true)); }
$$ = new AstMemberDType($<fl>1, *$1, VFlagChildDType(), GRAMMARP->m_memDTypep->cloneTree(true));
PARSEP->tagNodep($$);
}
| id variable_dimensionListE '=' variable_declExpr
{ $4->v3error("Unsupported: Initial values in struct/union members."); }
| idSVKwd { $$ = NULL; }
@ -3874,6 +3876,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
// Remember the last variable created, so we can attach attributes to it in later parsing
GRAMMARP->m_varAttrp = nodep;
PARSEP->tagNodep(GRAMMARP->m_varAttrp);
return nodep;
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" ?>
<!-- DESCRIPTION: Verilator output: XML representation of netlist -->
<verilator_xml>
<files>
<file id="a" filename="AstRoot" language="1800-2012"/>
<file id="b" filename="COMMAND_LINE" language="1800-2012"/>
<file id="c" filename="INTERNAL_VERILATOR_DEFINE" language="1800-2012"/>
<file id="d" filename="input.vc" language="1800-2012"/>
<file id="e" filename="t/t_xml_tag.v" language="1800-2012"/>
</files>
<netlist>
<module fl="e6" name="m">
<var fl="e8" name="clk_ip" tag="clk_ip"/>
<var fl="e9" name="rst_ip"/>
<var fl="e10" name="foo_op" tag="foo_op"/>
<typedef fl="e14" name="my_struct"/>
<var fl="e23" name="this_struct"/>
</module>
<typetable fl="a0">
<basicDType fl="e8" name="logic"/>
<structdtype fl="e14">
<memberdtype fl="e15" name="clk" tag="this is clk"/>
<memberdtype fl="e16" name="k"/>
<memberdtype fl="e17" name="enable" tag="enable"/>
<memberdtype fl="e18" name="data" tag="data"/>
</structdtype>
<basicDType fl="e15" name="logic"/>
<basicDType fl="e16" name="logic"/>
<basicDType fl="e17" name="logic"/>
<basicDType fl="e18" name="logic"/>
<refdtype fl="e23" name="my_struct"/>
</typetable>
</netlist>
</verilator_xml>

20
test_regress/t/t_xml_tag.pl Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2012 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");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile (
verilator_flags2 => ['--xml-only'],
verilator_make_gcc => 0,
);
ok(files_identical("$out_filename", "t/$Self->{name}.out"));
1;

View File

@ -0,0 +1,25 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Chris Randall.
module m
(
input clk_ip, // verilator tag clk_ip
input rst_ip,
output foo_op); // verilator tag foo_op
// This is a comment
typedef struct packed {
logic clk; /* verilator tag this is clk */
logic k; /* verilator lint_off UNUSED */
logic enable; // verilator tag enable
logic data; // verilator tag data
} my_struct;
// This is a comment
my_struct this_struct;
endmodule