⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vpassert

📁 Verilog Parser in Perl
💻
📖 第 1 页 / 共 4 页
字号:
		}	    }	    $hit or die "vpassert %Error: $filename: Couldn't find symbol insertion point in $mod\n";	}    }    $#Endmodule_Inserts < 0	or die "vpassert %Error: $filename: Couldn't find endmodule\n";    # Put out the processed file    print "Got_Change? $Got_Change  $outname\n"	if ($Debug);    if ($Got_Change) {	my $date = localtime;	$fh->open(">$outname") or die "%Error: Can't write $outname.";	if ($Opt_Line) {	    print $fh "`line 1 \"$filename\" 0\n";	}	# No newline so line counts not affected	print $fh "/* Generated by vpassert; File:\"$filename\" */";	my $out = join('',map {$_->[1]} @Sendout);	# Simplify redundant `lines to save space	$out =~ s%(`line[^\n]*)\n[ \t\n]*(`line[^\n]*\n)%$2%mg;	print $fh $out;	$fh->close;	if (defined $File_Mtime{$filename}) {	    utime $File_Mtime{$filename}, $File_Mtime{$filename}, $outname;	}    }    return $Got_Change;}#----------------------------------------------------------------------sub bitwidth {    # Take a string like "{foo[5:0],bar} and return bit width (7 in this case)    my $statement = shift;    my $bits = 0;    foreach my $sig (split /,\{\]/, $statement) {	if ($sig =~ /[a-z].* \[ (-?[0-9]+) : (-?[0-9]+) \]/x) {	    $bits += ($1 - $2) + 1;	} elsif ($sig =~ /[a-z]/) {	    $bits ++;	}    }    return $bits;}#----------------------------------------------------------------------#----------------------------------------------------------------------#----------------------------------------------------------------------sub vpassert_db_read_file {    # Read when the unprocessed files were last known to not need processing    my $filename = shift;    my $fh = IO::File->new("<$filename") or return;  # no error if fails    while (my $line = $fh->getline) {	chomp $line;	if ($line =~ /^switch\s*(.*$)/) {	    my $old = $1;	    my $now = _switch_line();	    $old =~ s/\s+//g;	    $now =~ s/\s+//g;	    $Last_ArgsDiffer = ($old ne $now);	} else {	    my ($tt_cmd, $tt_file, $tt_mtime) = split(/\t/,$line);	    $tt_cmd .= "";	# Warning removal	    $File_Mtime_Read{$tt_file} = $tt_mtime;	    $File_Mtime_Read_Used{$tt_file} = 0;	}    }    $fh->close;}sub vpassert_db_write_file {    # Save which unprocessed files did not need processing    my $filename = shift;    my $fh = IO::File->new(">$filename") or die "%Error: $! $filename.\n";    $fh->print ("switch\t"._switch_line()."\n");    foreach my $file (sort (keys %File_Mtime)) {	$fh->print ("unproc\t$file\t$File_Mtime{$file}\n");    }    $fh->close;}#----------------------------------------------------------------------sub vpassert_recursive_prelude {    # What to do before processing any files    my $destdir = shift;    $destdir .= "/"		if ($destdir !~ /[\\\/]$/);    %File_Mtime = ();    %File_Mtime_Read = ();    vpassert_db_read_file ("${destdir}/.vpassert_skipped_times");    form_conversions_regexp();    if (! -d $destdir) {	mkdir ($destdir,0777) or die "%Error: Can't mkdir $destdir\n";    }    # Don't include directory in time saving, as path may change dep how run    my $dest_mtime = $File_Mtime_Read{"vpassert"} || 0;    if (!$Opt_Date	|| ($Prog_Mtime > $dest_mtime)	|| $Last_ArgsDiffer) {	# Flush the whole read cache	%File_Mtime_Read = ();	print "\t    VPASSERT (or overall flags) changed... Two minutes...\n";	print "\t    Mtime = $Prog_Mtime\n" if $Debug;    }    #print "FF $Opt_Date, $Prog_Mtime, $dest_mtime, $Opt_Vericov, $Last_Vericov\n";    $File_Mtime{"vpassert"} = $Prog_Mtime;    $File_Mtime_Read_Used{"vpassert"} = 1;}sub vpassert_recursive_postlude {    my $destdir = shift;    $destdir .= "/"		if ($destdir !~ /[\\\/]$/);    # What to do after processing all files    # Check for deletions    foreach my $srcfile (keys %File_Mtime_Read) {	if (defined $File_Mtime_Read_Used{$srcfile}	    && !$File_Mtime_Read_Used{$srcfile}) {	    (my $basefile = $srcfile) =~ s/.*\///;	    my $destfile = "$destdir$basefile";	    # A file with the same basename may now be in a different dir,	    # and already processed, so don't delete it.	    if (!$File_Dest{$destfile}) {		print "\t    vpassert: Deleted? $srcfile\n" if !$Opt_Quiet;		unlink $destfile;	    }	}    }    vpassert_db_write_file ("${destdir}/.vpassert_skipped_times");}sub vpassert_recursive {    # Recursively process this directory or file argument    my $srcdir = shift;    my $destdir = shift;    print "Recursing $srcdir $destdir\n" if ($Debug);    if (-d $srcdir) {	$srcdir .= "/"		if ($srcdir !~ /[\\\/]$/);	$destdir .= "/"		if ($destdir !~ /[\\\/]$/);	my $dh = new IO::Dir $srcdir or die "%Error: Could not directory $srcdir.\n";	while (defined (my $basefile = $dh->read)) {	    my $srcfile = $srcdir . $basefile;	    if ($Opt->libext_matches($srcfile)) {		next if -d $srcfile;		vpassert_process_one($srcfile, $destdir);	    }	}	$dh->close();    } else {	# Plain file	vpassert_process_one ($srcdir, $destdir, 1);    }}use vars (qw(%file_directory));sub vpassert_process_one {    # Process one file, keeping cache consistent    my $srcfile = shift;    my $destdir = shift;    (my $basefile = $srcfile) =~ s!.*[/\\]!!;    my $destfile = "$destdir$basefile";    $File_Dest{$destfile} = 1;    my $src_mtime = (stat($srcfile))[9];    $src_mtime ||= 0;    my $dest_mtime = $File_Mtime_Read{$srcfile} || 0;    $File_Mtime_Read_Used{$srcfile} = 1;    # Mark times    #print "BCK $basefile $src_mtime, $dest_mtime\n";    $File_Mtime{$srcfile} = $src_mtime;    if ($src_mtime != $dest_mtime) {	my $no_output = 0;	unlink $destfile;	$Total_Files++;	if (! vpassert_process ($srcfile, $destfile, $Opt_AllFiles)) {	    # Didn't need to do processing	    $no_output = 1;	    print "nooutput: vpassert_process ($srcfile, $destfile,0 )\n" if ($Debug);	    copy($srcfile,$destfile);	} else {	    # Make sure didn't clobber another directory's file	    print "madenew:  vpassert_process ($srcfile, $destfile,0 )\n" if ($Debug);	    if ($file_directory{$destfile}) {		my $old = $file_directory{$destfile};		die "%Error: Two files with same basename: $srcfile, $old\n";		# This warning is to prevent search order dependence in the		# verilog search path.  It also makes sure we don't clobber		# one file with another by the same name in the .vpassert directory	    }	}	if (!$Opt_Quiet) {	    print "  VPASSERT'ing file ($Total_Files) $srcfile ",	    ($dest_mtime ? "(Changed)":"(New)"), ($no_output ? " (no-output)" : ""),"\n";	}    }    $file_directory{$destfile} = $srcfile;}######################################################################################################################################################################################################################################################################################### Parser functions called by Verilog::Parserpackage Verilog::Vpassert::Parser; ## no criticrequire Exporter;use Verilog::Parser;use base qw(Verilog::Parser);BEGIN {    # Symbols to alias to global scope    use vars qw(@GLOBALS);    @GLOBALS = qw	(	 $Debug	 @Sendout	 $Last_Task	 $Last_Module	 $Opt_Chiponly	 $Opt_Vericov	 $ReqAck_Num	 $Vericov_Enabled	 %Vpassert_Conversions	 %Vpassert_Chiponly_Rename	 %Insure_Symbols	 @Endmodule_Inserts	 );    foreach (@GLOBALS) {	my ($type,$sym) = /^(.)(.*)$/;	*{"$sym"} = \${"::$sym"} if ($type eq "\$");	*{"$sym"} = \%{"::$sym"} if ($type eq "%");	*{"$sym"} = \@{"::$sym"} if ($type eq "@");    }}use strict;use vars (@GLOBALS,	  qw ( $Last_Keyword	       @Last_Symbols	       @Last_Number_Ops	       $Need_Vpassert_Symbols	       @Params	       $Param_Num	       $Parens	       $In_Message	       ));use Verilog::Parser;sub new {    my $class = shift;    my $self = $class->SUPER::new();    bless $self, $class;    # State of the parser    # These could be put under the class, but this is faster and we only parse    # one file at a time    @Endmodule_Inserts = ();    $Last_Keyword = "";    @Last_Symbols = ();    @Last_Number_Ops = ();    $Last_Task = "";    $Last_Module = "";    $Vericov_Enabled = $Opt_Vericov;    $Need_Vpassert_Symbols = 0;    $Param_Num = 0;    $Parens = 0;    $In_Message = 0;    #%module_symbols = ();    %Insure_Symbols = ();    @Params = ();    return $self;}sub keyword {    # Callback from parser when a keyword occurs    my ($parser, $token) = @_;    my $since = $parser->unreadback(); $parser->unreadback('');    $Last_Keyword = $token;    @Last_Symbols = ();    @Last_Number_Ops = ();    if ($Opt_Vericov && (($token eq "case") || ($token eq "casex") || ($token eq "casez"))) {	push @Sendout, [$parser->lineno, $since];	::sendout ("\n/*summit implicit off*/\n") if $Vericov_Enabled;	push @Sendout, [$parser->lineno, $token];    }    elsif ($Opt_Vericov && ($token eq "endcase")) {	push @Sendout, [$parser->lineno, $since . $token];	::sendout ("\n/*summit implicit on*/\n") if $Vericov_Enabled;    }    elsif ($token eq "endmodule") {	if ($#Endmodule_Inserts >= 0) {	    my $ins = join('',@Endmodule_Inserts);	    my $lineno = $parser->lineno;	    $ins =~ s!/\*vpassert_endmod_line\*/!$lineno!g;	    ::sendout ("/*vpassert*/ ".$ins." /*vpassert*/");	    @Endmodule_Inserts = ();	}	push @Sendout, [$parser->lineno, $since . $token];    }    else {	push @Sendout, [$parser->lineno, $since . $token];    }}sub symbol {    # Callback from parser when a symbol occurs    my ($parser, $token) = @_;    my $since = $parser->unreadback(); $parser->unreadback('');    if ($token eq "__LINE__") { $token = $parser->lineno(); }    if ($token eq "__FILE__") { $token = $parser->filename(); }    if ($In_Message) {	$Params[$Param_Num] .= $since . $token;    } else {	if ($Vpassert_Conversions {$token}		 || ($Opt_Chiponly && defined $Vpassert_Chiponly_Rename{$token} && !$Vpassert_Chiponly_Rename{$token})		 || ($Opt_NoPli && $token =~ /^\$/ && $Parens==0)) {	    push @Sendout, [$parser->lineno, $since];	    print "Callback SYMBOL $token\n"    if ($Debug);	    $In_Message = 1;	    $Param_Num = 1;	    @Params = ();	    $Params[0] = $token;	} elsif ($Opt_Chiponly && defined $Vpassert_Chiponly_Rename{$token}		 && $Vpassert_Chiponly_Rename{$token}) {	    push @Sendout, [$parser->lineno, $since . $Vpassert_Chiponly_Rename{$token}];	} else {	    # Actually a keyword; we check for that too	    push @Sendout, [$parser->lineno, $since . $token];	}    }    if ($Last_Keyword eq "task") {	$Last_Task = $token;	$Last_Keyword = "";	$Parens = 0;    }    if ($Last_Keyword eq "module") {	$Last_Module = $token;	$Last_Keyword = "";	$Need_Vpassert_Symbols = 1;	$ReqAck_Num = 1;	$Parens = 0;    }    push @Last_Symbols, $token;}sub number {    # Callback from parser when a number occurs    my ($parser, $token) = @_;    my $since = $parser->unreadback(); $parser->unreadback('');    if ($In_Message) {	print "Callback NUMBER $token\n"    if ($Debug);	$Params[$Param_Num] .= $since . $token;    } else {	push @Sendout, [0, $since . $token];    }    push @Last_Number_Ops, $token;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -