forked from github/verilator
Add /*verilator tag*/ for XML extraction applications.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
ba270e09a4
commit
264b888ef2
2
Changes
2
Changes
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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); }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
34
test_regress/t/t_xml_tag.out
Normal file
34
test_regress/t/t_xml_tag.out
Normal 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
20
test_regress/t/t_xml_tag.pl
Executable 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;
|
25
test_regress/t/t_xml_tag.v
Normal file
25
test_regress/t/t_xml_tag.v
Normal 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
|
Loading…
Reference in New Issue
Block a user