Reconsile parser with Verilog-Perl version, to enable more SV features

This commit is contained in:
Wilson Snyder 2009-05-07 18:28:05 -04:00
parent 851b022c7a
commit 4569278c53
13 changed files with 1450 additions and 494 deletions

View File

@ -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;
}

View File

@ -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:

View File

@ -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 $<

View File

@ -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];};
};

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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

View File

@ -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() {}

View File

@ -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;

View File

@ -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(); }

File diff suppressed because it is too large Load Diff

View File

@ -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;