Reconsile parser with Verilog-Perl version, to enable more SV features
This commit is contained in:
parent
851b022c7a
commit
4569278c53
|
|
@ -81,7 +81,7 @@ sub diff_file {
|
|||
|
||||
filter ($a, $tmp_a);
|
||||
filter ($b, $tmp_b);
|
||||
system("diff $tmp_a $tmp_b");
|
||||
system("diff -u $tmp_a $tmp_b");
|
||||
unlink $tmp_a;
|
||||
unlink $tmp_b;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,20 @@
|
|||
|
||||
# DESCRIPTION: Diff bison files
|
||||
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use strict;
|
||||
|
||||
my $Debug;
|
||||
our $Debug;
|
||||
our $Opt_Unsup;
|
||||
|
||||
if (! GetOptions (
|
||||
#"help" => \&usage,
|
||||
"debug" => sub { $Debug = 1; },
|
||||
"unsup!" => \$Opt_Unsup, # Ignore unsupported
|
||||
)) {
|
||||
die "usage();"
|
||||
}
|
||||
|
||||
diff($ARGV[0],$ARGV[1]);
|
||||
|
||||
|
|
@ -53,16 +63,23 @@ sub prep {
|
|||
next if $line !~ /%token/;
|
||||
$skip = 2;
|
||||
}
|
||||
|
||||
if ($Opt_Unsup) {
|
||||
$line =~ s!//UNSUP!|!g;
|
||||
$line =~ s!(\s+)\|(\s+)!$1$2!g; # As "UNSUP" often replaces "|"
|
||||
}
|
||||
|
||||
# %type<foo>
|
||||
$line =~ s/^(%\S+)<(\S+)>/$1/;
|
||||
# rule<foo>
|
||||
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
|
||||
# Productions
|
||||
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
|
||||
|
||||
$fho->print($line);
|
||||
}
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./bisondiff $WUP/Verilog/Parser/VParseBison.y ../src/verilog.y"
|
||||
# compile-command: "./bisondiff --unsup $WUP/Verilog/Parser/VParseBison.y ../src/verilog.y"
|
||||
# End:
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
|
|||
V3ParseBison.h: V3ParseBison.c
|
||||
|
||||
# Have only one output file in this rule to prevent parallel make issues
|
||||
V3ParseBison.c: verilog.y $(HEADERS) bisonpre
|
||||
V3ParseBison.c: verilog.y $(BISONPRE)
|
||||
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
|
||||
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $<
|
||||
|
||||
|
|
|
|||
24
src/V3Ast.h
24
src/V3Ast.h
|
|
@ -169,12 +169,25 @@ public:
|
|||
class AstAttrType {
|
||||
public:
|
||||
enum en {
|
||||
BITS,
|
||||
RANGE_LSB,
|
||||
ARRAY_LSB,
|
||||
SCOPE_TEXT
|
||||
BITS, // V3Const converts to constant
|
||||
RANGE_LSB, // V3Const converts to constant
|
||||
ARRAY_LSB, // V3Const converts to constant
|
||||
//
|
||||
VAR_CLOCK, // V3LinkParse moves to AstVar::attrScClocked
|
||||
VAR_CLOCK_ENABLE, // V3LinkParse moves to AstVar::attrClockEn
|
||||
VAR_PUBLIC, // V3LinkParse moves to AstVar::sigPublic
|
||||
VAR_PUBLIC_FLAT, // V3LinkParse moves to AstVar::sigPublic
|
||||
VAR_ISOLATE_ASSIGNMENTS // V3LinkParse moves to AstVar::attrIsolateAssign
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
"BITS", "RANGE_LSB", "ARRAY_LSB",
|
||||
"VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC", "VAR_PUBLIC_FLAT",
|
||||
"VAR_ISOLATE_ASSIGNMENTS"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
inline AstAttrType () {};
|
||||
inline AstAttrType (en _e) : m_e(_e) {};
|
||||
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {};
|
||||
|
|
@ -203,6 +216,7 @@ public:
|
|||
IMPLICIT,
|
||||
REG,
|
||||
TRIWIRE,
|
||||
PORT, // Temp type used in parser only
|
||||
BLOCKTEMP,
|
||||
MODULETEMP,
|
||||
STMTTEMP,
|
||||
|
|
@ -217,7 +231,7 @@ public:
|
|||
static const char* names[] = {
|
||||
"?","GPARAM","LPARAM","GENVAR",
|
||||
"INTEGER","INPUT","OUTPUT","INOUT",
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE",
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE","PORT",
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
|
||||
return names[m_e];};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ void AstNode::dump(ostream& os) {
|
|||
if (!widthSized()) os<<"/"<<widthMin();
|
||||
if (name()!="") os<<" "<<name();
|
||||
}
|
||||
|
||||
void AstAttrOf::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" ["<<attrType().ascii()<<"]";
|
||||
}
|
||||
void AstCast::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" sz"<<size();
|
||||
|
|
@ -215,7 +220,6 @@ void AstCell::dump(ostream& str) {
|
|||
this->AstNode::dump(str);
|
||||
if (modp()) { str<<" -> "; modp()->dump(str); }
|
||||
else { str<<" ->UNLINKED:"<<modName(); }
|
||||
if (pinStar()) str<<" [.*]";
|
||||
}
|
||||
void AstCellInline::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
|
|
|
|||
|
|
@ -294,6 +294,8 @@ public:
|
|||
AstRange* arrayp(int dim) const; // op2 = Range for specific dimension #
|
||||
AstNode* initp() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const)
|
||||
void initp(AstNode* nodep) { setOp3p(nodep); }
|
||||
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
||||
AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse
|
||||
bool hasSimpleInit() const { return (op3p() && !op3p()->castInitArray()); }
|
||||
void rangep(AstRange* nodep) { setOp1p(nodep); }
|
||||
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
||||
|
|
@ -571,6 +573,7 @@ public:
|
|||
virtual bool broken() const { return (m_modVarp && !m_modVarp->brokeExists()); }
|
||||
virtual string name() const { return m_name; } // * = Pin name, ""=go by number
|
||||
void name(const string& name) { m_name = name; }
|
||||
bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked
|
||||
int pinNum() const { return m_pinNum; }
|
||||
void exprp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
|
||||
|
|
@ -631,14 +634,13 @@ private:
|
|||
string m_name; // Cell name
|
||||
string m_origName; // Original name before dot addition
|
||||
string m_modName; // Module the cell instances
|
||||
bool m_pinStar; // Pin list has .*
|
||||
AstModule* m_modp; // [AfterLink] Pointer to module instanced
|
||||
public:
|
||||
AstCell(FileLine* fl, const string& instName, const string& modName,
|
||||
AstPin* pinsp, AstPin* paramsp, AstRange* rangep)
|
||||
: AstNode(fl)
|
||||
, m_name(instName), m_origName(instName), m_modName(modName)
|
||||
, m_pinStar(false), m_modp(NULL) {
|
||||
, m_modp(NULL) {
|
||||
addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); }
|
||||
ASTNODE_NODE_FUNCS(Cell, CELL)
|
||||
// No cloneRelink, we presume cloneee's want the same module linkages
|
||||
|
|
@ -652,8 +654,6 @@ public:
|
|||
void origName(const string& name) { m_origName = name; }
|
||||
string modName() const { return m_modName; } // * = Instance name
|
||||
void modName(const string& name) { m_modName = name; }
|
||||
bool pinStar() const { return m_pinStar; }
|
||||
void pinStar(bool flag) { m_pinStar = flag; }
|
||||
AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
|
||||
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values
|
||||
AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged)
|
||||
|
|
@ -1717,13 +1717,14 @@ private:
|
|||
AstAttrType m_attrType; // What sort of extraction
|
||||
int m_dimension; // Dimension number (0 is leftmost), for ARRAY_LSB extractions
|
||||
public:
|
||||
AstAttrOf(FileLine* fl, AstAttrType attrtype, AstNode* fromp, int dimension=0)
|
||||
AstAttrOf(FileLine* fl, AstAttrType attrtype, AstNode* fromp=NULL, int dimension=0)
|
||||
: AstNode(fl) {
|
||||
setOp1p(fromp); m_attrType = attrtype; m_dimension = dimension; }
|
||||
setNOp1p(fromp); m_attrType = attrtype; m_dimension = dimension; }
|
||||
ASTNODE_NODE_FUNCS(AttrOf, ATTROF)
|
||||
AstNode* fromp() const { return op1p(); }
|
||||
AstAttrType attrType() const { return m_attrType; }
|
||||
int dimension() const { return m_dimension; }
|
||||
virtual void dump(ostream& str=cout);
|
||||
};
|
||||
|
||||
struct AstScopeName : public AstNode {
|
||||
|
|
|
|||
|
|
@ -1042,8 +1042,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstAttrOf* nodep, AstNUser*) {
|
||||
// Don't iterate children, don't want to loose VarRef.
|
||||
if (nodep->attrType()==AstAttrType::SCOPE_TEXT) {
|
||||
} else if (nodep->attrType()==AstAttrType::BITS) {
|
||||
if (nodep->attrType()==AstAttrType::BITS) {
|
||||
if (!nodep->fromp() || !nodep->fromp()->widthMin()) nodep->v3fatalSrc("Unsized expression");
|
||||
V3Number num (nodep->fileline(), 32, nodep->fromp()->widthMin());
|
||||
replaceNum(nodep, num); nodep=NULL;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,17 @@ private:
|
|||
}
|
||||
}
|
||||
// Convert .* to list of pins
|
||||
if (nodep->modp() && nodep->pinStar()) {
|
||||
bool pinStar = false;
|
||||
for (AstPin* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
|
||||
nextp = pinp->nextp()->castPin();
|
||||
if (pinp->dotStar()) {
|
||||
if (pinStar) pinp->v3error("Duplicate .* in a cell");
|
||||
pinStar = true;
|
||||
// Done with this fake pin
|
||||
pinp->unlinkFrBack()->deleteTree(); pinp=NULL;
|
||||
}
|
||||
}
|
||||
if (nodep->modp() && pinStar) {
|
||||
// Note what pins exist
|
||||
UINFO(9," CELL .* connect "<<nodep<<endl);
|
||||
V3SymTable ports; // Symbol table of all connected port names
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ private:
|
|||
bool m_inModDot; // We're inside module part of dotted name
|
||||
AstParseRefExp m_exp; // Type of data we're looking for
|
||||
AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref
|
||||
AstVar* m_varp; // Variable we're under
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
|
|
@ -225,6 +226,42 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
m_varp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_varp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstAttrOf* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->attrScClocked(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->attrClockEn(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->sigPublic(true); m_varp->sigModPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->sigPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->attrIsolateAssign(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// Default: Just iterate
|
||||
checkExpected(nodep); // So we detect node types we forgot to list here
|
||||
|
|
@ -237,6 +274,7 @@ public:
|
|||
m_inModDot = false;
|
||||
m_exp = AstParseRefExp::NONE;
|
||||
m_baseTextp = NULL;
|
||||
m_varp = NULL;
|
||||
rootp->accept(*this);
|
||||
}
|
||||
virtual ~LinkParseVisitor() {}
|
||||
|
|
|
|||
|
|
@ -156,9 +156,9 @@ sub clean_output {
|
|||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
(my $basename = tmp_prefix()) =~ s!.*/!!;
|
||||
(my $basename = tmp_prefix().".y") =~ s!.*/!!;
|
||||
$basename = quotemeta($basename);
|
||||
(my $newbase = output_prefix()) =~ s!.*/!!;
|
||||
(my $newbase = $Opt_Input) =~ s!.*/!!;
|
||||
|
||||
if ($is_output) {
|
||||
my %state_line; my $l=0;
|
||||
|
|
@ -320,6 +320,7 @@ sub clean_input {
|
|||
$_=$insert; eval("$code; \$_;"); $insert = $_;
|
||||
#print "COPY out $insert\n";
|
||||
while ($insert =~ s/[ \t\n]+\n/\n/go) {}
|
||||
while ($insert =~ s/\n/ /go) {} # Optional - preserve line numbering
|
||||
$line =~ s/{HERE}/$insert/;
|
||||
}
|
||||
push @lines, $line;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "V3Number.h"
|
||||
#include "V3ParseBison.h" // Generated by bison
|
||||
|
||||
extern void yyerror(char*);
|
||||
extern void yyerror(const char*);
|
||||
extern void yyerrorf(const char* format, ...);
|
||||
|
||||
#define STATE_VERILOG_RECENT S05 // State name for most recent Verilog Version
|
||||
|
|
@ -99,7 +99,7 @@ void V3Read::verilatorCmtBad(const char* textp) {
|
|||
|
||||
//======================================================================
|
||||
|
||||
void yyerror(char* errmsg) {
|
||||
void yyerror(const char* errmsg) {
|
||||
V3Read::fileline()->v3error(errmsg);
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ escid \\[^ \t\f\r\n]+
|
|||
"repeat" { FL; return yREPEAT; }
|
||||
"scalared" { FL; return ySCALARED; }
|
||||
"specify" { FL; return ySPECIFY; }
|
||||
"specparam" { FL; return yaTIMINGSPEC; }
|
||||
"specparam" { FL; return ySPECPARAM; }
|
||||
"supply0" { FL; return ySUPPLY0; }
|
||||
"supply1" { FL; return ySUPPLY1; }
|
||||
"task" { FL; return yTASK; }
|
||||
|
|
@ -705,17 +705,17 @@ escid \\[^ \t\f\r\n]+
|
|||
|
||||
/* Identifiers and numbers */
|
||||
<V95,V01,V05,S05,PSL>{
|
||||
{escid} { yylval.strp = V3Read::newString
|
||||
{escid} { yylval.strp = V3Read::newString
|
||||
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
|
||||
return yaID;
|
||||
}
|
||||
return yaID__ETC;
|
||||
}
|
||||
|
||||
{id} { yylval.strp = V3Read::newString(AstNode::encodeName(string(yytext)));
|
||||
return yaID;
|
||||
}
|
||||
{id} { yylval.strp = V3Read::newString(AstNode::encodeName(string(yytext)));
|
||||
return yaID__ETC;
|
||||
}
|
||||
|
||||
\"[^\"\\]*\" { yylval.strp = V3Read::newString(yytext+1,yyleng-2);
|
||||
return yaSTRING;
|
||||
\"[^\"\\]*\" { yylval.strp = V3Read::newString(yytext+1,yyleng-2);
|
||||
return yaSTRING;
|
||||
}
|
||||
\" { yy_push_state(STRING); yymore(); }
|
||||
|
||||
|
|
|
|||
1791
src/verilog.y
1791
src/verilog.y
File diff suppressed because it is too large
Load Diff
|
|
@ -22,6 +22,8 @@ module t;
|
|||
incr(global,global,32'h10);
|
||||
if (global != 32'h17) $stop;
|
||||
nop(32'h11);
|
||||
empty;
|
||||
empty();
|
||||
|
||||
global = 32'h00000001;
|
||||
flipupperbit(global,4'd4);
|
||||
|
|
@ -89,6 +91,9 @@ module t;
|
|||
end
|
||||
endtask
|
||||
|
||||
task empty;
|
||||
endtask
|
||||
|
||||
task flipupperbit;
|
||||
inout [31:0] vector;
|
||||
input [3:0] bitnum;
|
||||
|
|
|
|||
Loading…
Reference in New Issue